
#include "../include/CSerial.h"
#include "../include/CLog.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <unistd.h>
#include <time.h>
#include <stdlib.h>
#include <sys/time.h>
#include "../include/XZ_F31_API_LINUX.h"
#include "../include/DES.h"
#include "../include/libusb.h"
#include "../include/StringOprate.h"

#define VendorID  0x0483
#define ProductID 0x3021
libusb_device_handle *dev_handle= NULL;
libusb_context *ctx= NULL;
CLog g_Log(true); //log class obj
static CSerial g_Com; //serial class obj;
bool g_bSMmode = false; //键盘加密模式 默认为非国密
int  g_SendCmd = 1;   //0 - 取键值直接读串口; 1 - 发送指令取键值    怡化版本是1
bool g_bLogClearSecret = false; //true,去掉敏感信息

int g_MacBlockNum= 1024; //一次计算3K数据

int g_IsCom = false; //串口方式通讯

int g_nLogLevel = 1;
// #define g_Log.WriteLog(str)  printf("line:%d, func:%s : %s\n", __LINE__, __FUNCTION__, str)

#define				MAX_TIME_OUT					5
#define				MIN_TIME_OUT					2
CCriticalSection g_mutex;

extern "C"
{
int foundusbdev(libusb_device **dev,int count)
{
    ssize_t i;
    for(i = 0; i < count; i++)
    {
        struct libusb_device_descriptor desc;
        int r = libusb_get_device_descriptor(dev[i],&desc);
        if (r < 0)
        {
	    g_Log.WriteLog("failed to get device descriptor");
            return -1;
        }
        if((desc.idVendor == 0x0483)&&(desc.idProduct == 0x3021))
        {
            return 0;
        }
    }
    return -1;
}

int tim_subtract(struct timeval *result, struct timeval *x, struct timeval *y)
{
	if (x->tv_sec > y->tv_sec)
		return -1;
	if ((x->tv_sec == y->tv_sec) && (x->tv_usec > y->tv_usec))
		return -1;
	result->tv_sec = (y->tv_sec - x->tv_sec);
	result->tv_usec = (y->tv_usec - x->tv_usec);
	if (result->tv_usec < 0)
	{
		result->tv_sec--;
		result->tv_usec += 1000000;
	}
	return 0;
}


//serial -------
//向串口发送数据,成功返回实际发送的字节数
int SUNSON_SendDataToCom(unsigned char *str, int length)
{
	g_Com.ClearTxRx();
	int i;
	i = g_Com.Write_Comm(str, length);
	return (i);
}

//从串口读出数据
int SUNSON_ReadDataFromCom(unsigned char *str, int length)
{
	int iactuallen = g_Com.Read_Comm(str, length);
	return iactuallen;
}
int SUNSON_ReadDataFromComEx(unsigned char *str, int length)
{
	int iactuallen = g_Com.Read_Comm(str, length, 1);
	return iactuallen;
}

//从串口读一个字节数据
int SUNSON_ReadOneByteFromCom(unsigned char *str)
{
	unsigned char str1[2];
	memset(str1, 0, 2);
	int i;
	g_Com.SetTimeOut(1);
	i = g_Com.Read_Comm(str1, 1);
	if (i == 1)
	{
		str[0] = str1[0];
		return 1;
	}
	else
		return 0;
}

/////////////////////////////////////////////////////////
//串口有效数据
//返回数据格式为02h+<CMD>+<Ln>+<DATA>
///////////////////////////////////////////////////////
int SUNSON_Read_Com_String(bool bDelaytime,unsigned char *str, bool bflag=false);
int SUNSON_Read_Com_String(bool bDelaytime, unsigned char *str, bool bflag)
{
	//g_Log.WriteLog("SUNSON_Read_Com_String -begin");
	str[0] = 0x00;
	str[1] = 0x00;
	unsigned char ucConnect[4];
	memset(ucConnect, 0, 4);
	int resultlen = 0;
	int i = -1;
	int nDelayCount = -1;
	if (bDelaytime)
		nDelayCount = 20;
	else
		nDelayCount=3;
	g_Com.SetTimeOut(10);
	
	struct timeval start, stop;
	gettimeofday(&start, 0);
	int nTimeOut = (bDelaytime)?MAX_TIME_OUT:MIN_TIME_OUT;
	
	if(bflag)
	{
		nTimeOut = 180; //3分钟
	}

	//char csLog[1024]={0};
	//sprintf(csLog, "nT= %d, begin=%d", nTimeOut, start.tv_sec);
	//g_Log.WriteLog(csLog);
	
	
	while (1)
	{
		//g_Log.WriteLog("1");
		gettimeofday(&stop, 0);
		//tim_subtract(&diff, &start, &stop);
		//sprintf(csLog, "nT= %d, end=%d, dif=%d", nTimeOut, stop.tv_sec, stop.tv_sec-start.tv_sec);
		//g_Log.WriteLog(csLog);

		i = SUNSON_ReadDataFromCom(ucConnect,1);
		//g_Log.WriteLog("2");
		if ((stop.tv_sec - start.tv_sec) >= nTimeOut) //超时
		{
			g_Log.WriteLog("timeout");
			return -1;
		}
		else if (ucConnect[0] == 0x02)
		{
			break;
		}
	}
	//g_Log.WriteLog("SUNSON_Read_Com_String -jx");
	if (ucConnect[0] == 0x02)
	{
		i = SUNSON_ReadDataFromCom(ucConnect, 3);
		if (i <= 0)
		{
			return 0;
		}
		resultlen = ucConnect[1] * 256 + ucConnect[2]; //数据长度
		if (ucConnect[0] == 0x45)
		{
			i = SUNSON_ReadDataFromCom(ucConnect, 1);
			if (i <= 0)
			{
				return 0;
			}
			str[0] = ucConnect[0];
			return 0;
		}
		else if (ucConnect[0] == 0x53)
		{
			unsigned char *str1 = new unsigned char[resultlen];
			memset(str1, 0, resultlen);
			i = SUNSON_ReadDataFromCom(str1, resultlen);
			if (i <= 0)
			{
				delete[] str1;
				str1 = NULL;
				return 0;
			}
			for (i = 0; i < resultlen; i++) //str1[1]为返回的有效数据的长度，数据包的第二位
				str[i] = str1[i];
			delete[] str1;
			str1 = NULL;
			return resultlen; //返回有效数据长度
		}
	}
	else
		return 0;
	return 0;
}
int SUNSON_Read_Com_Stringex(bool bDelaytime, unsigned char *str, bool bflag=false);
int SUNSON_Read_Com_Stringex(bool bDelaytime, unsigned char *str, bool bflag)
{
	//g_Log.WriteLog("SUNSON_Read_Com_String -begin");
	str[0] = 0x00;
	str[1] = 0x00;
	unsigned char ucConnect[4];
	memset(ucConnect, 0, 4);
	int resultlen = 0;
	int i = -1;
	int nDelayCount = -1;
	if (bDelaytime)
		nDelayCount = 20;
	else
		nDelayCount=3;
	g_Com.SetTimeOut(10);
	
	struct timeval start, stop;
	gettimeofday(&start, 0);
	int nTimeOut = (bDelaytime)?MAX_TIME_OUT:MIN_TIME_OUT;
	
	if(bflag)
	{
		nTimeOut = 180; //3分钟
	}

	//char csLog[1024]={0};
	//sprintf(csLog, "nT= %d, begin=%d", nTimeOut, start.tv_sec);
	//g_Log.WriteLog(csLog);
	
	
	while (1)
	{
		//g_Log.WriteLog("1");
		gettimeofday(&stop, 0);
		//tim_subtract(&diff, &start, &stop);
		//sprintf(csLog, "nT= %d, end=%d, dif=%d", nTimeOut, stop.tv_sec, stop.tv_sec-start.tv_sec);
		//g_Log.WriteLog(csLog);

		i = SUNSON_ReadDataFromCom(ucConnect,1);
		//g_Log.WriteLog("2");
		if ((stop.tv_sec - start.tv_sec) >= nTimeOut) //超时
		{
			g_Log.WriteLog("timeout");
			return -1;
		}
		else if (ucConnect[0] == 0x02)
		{
			break;
		}
	}
	//g_Log.WriteLog("SUNSON_Read_Com_String -jx");
	if (ucConnect[0] == 0x02)
	{
		i = SUNSON_ReadDataFromCom(ucConnect, 3);
		if (i <= 0)
		{
			return 0;
		}
		resultlen = ucConnect[1] * 256 + ucConnect[2]; //数据长度
		if (ucConnect[0] == 0x45)
		{
			i = SUNSON_ReadDataFromCom(ucConnect, 1);
			if (i <= 0)
			{
				return 0;
			}
			str[0] = ucConnect[0];
			return 0;
		}
		else if (ucConnect[0] == 0x53)
		{
			unsigned char *str1 = new unsigned char[resultlen];
			memset(str1, 0, resultlen);
			i = SUNSON_ReadDataFromCom(str1, resultlen);
			if (i <= 0)
			{
				delete[] str1;
				str1 = NULL;
				return 0;
			}
			for (i = 0; i < resultlen; i++) //str1[1]为返回的有效数据的长度，数据包的第二位
				str[i] = str1[i];
			delete[] str1;
			str1 = NULL;
			return resultlen; //返回有效数据长度
		}
	}
	else
		return 0;
	return 0;
}

//获取指令执行后的结果信息
int SUNSON_ReturnST(unsigned char *errorinfo, bool bDelay=false);
int SUNSON_ReturnST(unsigned char *errorinfo, bool bDelay)
{
	errorinfo[0] = 0x00;
	errorinfo[1] = 0x00;

	unsigned char temp_return[100];
	memset(temp_return, 0, 100);
	unsigned char ucConnect[40];
	memset(ucConnect, 0, 40);
	g_Com.SetTimeOut(10);
	
	int i = -1;

	int nTimeOut = (bDelay)?MAX_TIME_OUT:MIN_TIME_OUT;
	struct timeval start, stop, diff;
	gettimeofday(&start, 0);
	while(1)
	{
		gettimeofday(&stop, 0);
		tim_subtract(&diff, &start, &stop);

		if (diff.tv_sec > nTimeOut) //超时
		{
			break;
		}

		i=SUNSON_ReadDataFromCom(ucConnect,1);
		if((i<=0 || ucConnect[0] != 0x02))
			continue;
		else
			break;
	}
	if (ucConnect[0] == 0x02)
	{
		i = SUNSON_ReadDataFromCom(ucConnect, 3);
		if (i <= 0)
		{
			return 0;
		}
		int resultlen = ucConnect[1] * 256 + ucConnect[2]; //数据长度
		if (ucConnect[0] == 0x45)//指令执行失败，并将错误信息代码返回
		{
			i = SUNSON_ReadDataFromCom(ucConnect, 1);
			if (i <= 0)
			{
				return 0;
			}
			errorinfo[0] = ucConnect[0];
			return 0;

		}
		else if (ucConnect[0] == 0x53)
		{
			unsigned char *str1 = new unsigned char[resultlen];
			memset(str1, 0, resultlen);
			i = SUNSON_ReadDataFromCom(str1, resultlen);
			if (i <= 0)
			{
				delete[] str1;
				str1 = NULL;
				return 0;
			}
			for (i = 0; i < resultlen; i++)
				errorinfo[i] = str1[i];
			delete[] str1;
			str1 = NULL;
			return 1; //返回有效数据长度
		}
	}
	else
		return 0;
	return 0;
}

//处理民生银行指令返回结果
int SUNSON_Read_Com_string_CMBC(bool bDelaytime,unsigned char *str,int nOvertime=4);
int SUNSON_Read_Com_string_CMBC(bool bDelaytime,unsigned char *str,int nOvertime) 
{
	str[0] = 0x00;

	unsigned char ucConnect[4];
	memset(ucConnect,0,4);
	
	int i=-1;
	int nTimeOut = 0; //5秒超时
	if(bDelaytime)
		nTimeOut = nOvertime*1000; //5秒超时;
	else
		nTimeOut = nOvertime*1000/2; //500ms超时;
	g_Com.SetTimeOut(10);

	struct timeval start, stop, diff;
	gettimeofday(&start, 0);
	while(1)
	{
		gettimeofday(&stop, 0);
		tim_subtract(&diff, &start, &stop);

		if (diff.tv_sec > nTimeOut) //超时
		{
			break;
		}

		i=SUNSON_ReadDataFromCom(ucConnect,1);
		if((i<=0 || ucConnect[0] != 0x02))
			continue;
		else
			break;
	}
	if(ucConnect[0]==0x02)
	{
		unsigned char str1[1024]={0};
		int ret =SUNSON_ReadDataFromCom(str1,91);
		if(ret<10) //返回的数据过短，返回失败
		{
			if(str1[0] == 0x45 && str1[1]==0x00 && str1[2]==0x01)
				str[0] = str1[3];//错误码
			return 0;
		}
		for(i=0;i<ret-1;i++) //最后一位是结尾符
			str[i]=str1[i];
		return ret-1; //返回有效数据长度
	}
	else
		return 0;
	return 0;
}

//Open the serial port
int SUNSON_SerialCloseCom(void);
int SUNSON_SerialOpenCom(const char *sztty, long nBaudrate)
{
	CCriticalSection autoSc;
	char CLog[1024] =
	{ 0 };
	g_Log.WriteLog("***打开串口***");
	sprintf(CLog, "SUNSON_SerialOpenCom,sztty = %s,nBaudrate = %d", sztty,
			(int) nBaudrate);
	// g_Log.WriteLog(CLog);

	SUNSON_SerialCloseCom();
	if (g_Com.OpenPort((char *) sztty, nBaudrate) == -1)
	{
		g_Log.WriteLog("打开串口失败！");
		return CMD_FAILS;
	}
	g_Log.WriteLog("打开串口成功！");


	return 1;
}

//Close the serial port
int SUNSON_SerialCloseCom(void)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("***关闭串口***");
	if (CMD_SUCCESS == g_Com.ClosePort())
	{
		g_Log.WriteLog("关闭串口成功！");
		return CMD_SUCCESS;
	}
	else
	{
		g_Log.WriteLog("关闭串口失败！");
		return CMD_FAILS;
	}
}

//获取按下的按键键值
int SUNSON_SerialScanGetKey(unsigned char *ucKeyValue);
int SUNSON_SerialScanKeyPress(unsigned char *ucKeyValue)
{
	CCriticalSection autoSc;
	if(g_SendCmd == 0)
	{
		unsigned char keyvalue[2];
		memset(keyvalue, 0, 2);
		int len = SUNSON_ReadOneByteFromCom(keyvalue);
		if (len == 1)
		{
			ucKeyValue[0] = keyvalue[0];
			char csLog[1024] =
			{ 0 };
			sprintf(csLog, "SUNSON_SerialScanKeyPress,ucValue = %02x", ucKeyValue[0]);
			g_Log.WriteLog(csLog);
			return 1;
		}
		return 0;
	}
	else
	{
		return SUNSON_SerialScanGetKey(ucKeyValue);
	}
}

int SUNSON_SerialScanGetKey(unsigned char *ucKeyValue) //被动模式获取键值，发送指令从键盘读取键值
{
	CCriticalSection autoSc;
	
	char csLog[1024] = {0};

	int i=0;
	int nReturnValue=-1;
	unsigned char CommandData[9]={0x1b,0x47,0x55,0x00,0x01,0x08,0x0D,0x0A};
	
	i=SUNSON_SendDataToCom(CommandData,8);
	if(i==8)
	{
		nReturnValue=SUNSON_Read_Com_String(false,ucKeyValue);
		if (nReturnValue>0)
		{
			if(ucKeyValue[0] == 0xFF)
				return 0;

			unsigned char temp[1024] = {0};
			hex_asc(ucKeyValue,temp,nReturnValue);
			sprintf(csLog,"SUNSON_SerialScanGetKey, key = %s",temp);
			g_Log.WriteLog(csLog);
		}
		else
		{
			unsigned char ResultInfo[2] = {0};
			hex_asc_char(ResultInfo[0],ResultInfo);
			sprintf(csLog,"SUNSON_SerialScanGetKey, ReturnInfo = 0x%c%c(失败)",ResultInfo[0],ResultInfo[1]);
			g_Log.WriteLog(csLog);
			ucKeyValue[0] = 0xFB;
		}
		return nReturnValue;		
	}
	else 
	{
		ucKeyValue[0] = 0xFB; 
		sprintf(csLog,"SUNSON_SerialScanGetKey, 指令发送失败");
		g_Log.WriteLog(csLog);
		return 0;
	}
}


//获取操作执行后的错误信息或成功标志信息
int SUNSON_SerialGetOperationResult(unsigned char *ucResultInfo)
{
	int flag = SUNSON_ReturnST(ucResultInfo);
	return flag;

}

// 与密码键盘相关指令封装
//B.1取EPP键盘版本号
int SUNSON_SerialGetVersionNo(unsigned char*VersionNo)
{
	CCriticalSection autoSc;
	if(g_nLogLevel >0)
		g_Log.WriteLog("---取键盘版本号---");
	char csLog[1024] =
	{ 0 };
	sprintf(csLog, "SUNSON_SerialGetVersionNo");
	if(g_nLogLevel>0)
		g_Log.WriteLog(csLog);
	*VersionNo = 0x00;

	int i = 0;
	int nReturnValue = -1;
	unsigned char CommandData[8] =
	{ 0x1b, 0x52, 0x45, 0x00, 0x01, 0x00, 0x0d, 0x0a };
	CommandData[5] = CommandData[0] ^ CommandData[1] ^ CommandData[2]
	^ CommandData[3] ^ CommandData[4];
	i = SUNSON_SendDataToCom(CommandData, 8);
	if (i == 8)
	{
		nReturnValue = SUNSON_Read_Com_String(false, VersionNo);
		if (nReturnValue > 0)
		{
			unsigned char temp[1024] =
			{ 0 };
			hex_asc(VersionNo, temp, nReturnValue);
			sprintf(csLog, "SUNSON_SerialGetVersionNo, DataResult = %s", temp);
			if(g_nLogLevel>0)
				g_Log.WriteLog(csLog);
		}
		else
		{
			unsigned char ResultInfo[2] =
			{ 0 };
			hex_asc_char(VersionNo[0], ResultInfo);
			sprintf(csLog, "SUNSON_SerialGetVersionNo, ReturnInfo = 0x%c%c(失败)",
				ResultInfo[0], ResultInfo[1]);
			g_Log.WriteLog(csLog);
		}
		return nReturnValue;
	}
	else
	{
		sprintf(csLog, "SUNSON_SerialGetVersionNo, ReturnInfo = 0x%02x(失败)",
			VersionNo[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}
//B.2系统复位
int SUNSON_SerialResetEpp(unsigned char *errorinfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---系统复位---");
	char csLog[1024] =
	{ 0 };
	sprintf(csLog, "SUNSON_SerialResetEpp");
	g_Log.WriteLog(csLog);
	*errorinfo = 0x00;

	int i = 0;
	int nReturnValue = -1;
	unsigned char CommandData[8] =
	{ 0x1b, 0x53, 0x46, 0x00, 0x01, 0x00, 0x0d, 0x0a };
	CommandData[5] = CommandData[0] ^ CommandData[1] ^ CommandData[2]
			^ CommandData[3] ^ CommandData[4];
	i = SUNSON_SendDataToCom(CommandData, 8);
	if (i == 8)
	{
		nReturnValue = SUNSON_ReturnST(errorinfo);
		if (nReturnValue == 1)
		{
			g_Log.WriteLog("SUNSON_SerialResetEpp,success!");
		}
		else
		{
			sprintf(csLog, "SUNSON_SerialResetEpp,failure! errorinfo = 0x%02x",
					errorinfo[0]);
			g_Log.WriteLog(csLog);
		}
		return nReturnValue;
	}
	else
	{
		sprintf(csLog, "SUNSON_SerialResetEpp,failure! errorinfo = 0x%02x",
				errorinfo[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}
//B.3自定义按键标志属性
int SUNSON_SerialSetKeyMark(long ActiveFunc, long ActiveFDK, long EndFunc,
		long EndFDK, unsigned char*errorinfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---自定义按键标志属性---");
	char csLog[1024] =
	{ 0 };
	sprintf(csLog,"SUNSON_SerialSetKeyMark,ActiveFunc = %ld,ActiveFDK = %ld,EndFunc = %ld,EndFDK = %ld",
			ActiveFunc, ActiveFDK, EndFunc, EndFDK);
	g_Log.WriteLog(csLog);
	*errorinfo = 0x00;

	int i = 0;
	int nReturnValue = -1;
	unsigned char data[4];
	memset(data, 0, 4);
	unsigned char CommandData[24];
	unsigned char XOR = 0x00;
	CommandData[0] = 0x1b;
	CommandData[1] = 0x53;
	CommandData[2] = 0x4B;
	CommandData[3] = 0x00;
	CommandData[4] = 0x11;

	for (int m = 0; m < 4; m++)
	{
		data[m] = (unsigned char) (((ActiveFunc) >> (8 * m)) & 0xFF);
	}
	CommandData[5] = data[0];
	CommandData[6] = data[1];
	CommandData[7] = data[2];
	CommandData[8] = data[3];

	for (int m = 0; m < 4; m++)
	{
		data[m] = (unsigned char) (((ActiveFDK) >> (8 * m)) & 0xFF);
	}
	CommandData[9] = data[0];
	CommandData[10] = data[1];
	CommandData[11] = data[2];
	CommandData[12] = data[3];

	for (int m = 0; m < 4; m++)
	{
		data[m] = (unsigned char) (((EndFunc) >> (8 * m)) & 0xFF);
	}
	CommandData[13] = data[0];
	CommandData[14] = data[1];
	CommandData[15] = data[2];
	CommandData[16] = data[3];

	for (int m = 0; m < 4; m++)
	{
		data[m] = (unsigned char) (((EndFDK) >> (8 * m)) & 0xFF);
	}
	CommandData[17] = data[0];
	CommandData[18] = data[1];
	CommandData[19] = data[2];
	CommandData[20] = data[3];

	for (i = 0; i < 21; i++)
	{
		XOR ^= CommandData[i];
	}
	CommandData[21] = XOR;
	CommandData[22] = 0x0d;
	CommandData[23] = 0x0a;
	i = SUNSON_SendDataToCom(CommandData, 24);
	if (i == 24)
	{
		nReturnValue = SUNSON_ReturnST(errorinfo);
		if (nReturnValue == 1)
		{
			g_Log.WriteLog("SUNSON_SerialSetKeyMark,success!");
		}
		else
		{
			sprintf(csLog, "SUNSON_SerialSetKeyMark,failure! errorinfo = 0x%02x",
					errorinfo[0]);
			g_Log.WriteLog(csLog);
		}
		return nReturnValue;
	}
	else
	{
		sprintf(csLog, "SUNSON_SerialSetKeyMark,failure! errorinfo = 0x%02x",
				errorinfo[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}

//B.4读取密钥校验值

// #define WFS_PIN_KCVNONE (0x0000)
// #define WFS_PIN_KCVSELF (0x0001)
// #define WFS_PIN_KCVZERO (0x0002)
 //
int SUNSON_SerialGetCheckValue(unsigned char ucCheckMode, unsigned char *CheckValue)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---读取密钥校验值---");
	char csLog[1024] =
	{ 0 };
	sprintf(csLog, "SUNSON_SerialGetCheckValue,mode = %02x", ucCheckMode);
	g_Log.WriteLog(csLog);
	*CheckValue = 0x00;

	int i = 0;
	int nReturnValue = -1;
	unsigned char CommandData[10] =
	{ 0x1b, 0x52, 0x43, 0x00, 0x02, 0x00, 0x00, 0x0d, 0x0a };
	CommandData[5] = ucCheckMode;
	CommandData[6] = CommandData[0] ^ CommandData[1] ^ CommandData[2]
			^ CommandData[3] ^ CommandData[4] ^ CommandData[5];
	i = SUNSON_SendDataToCom(CommandData, 9);
	if (i == 9)
	{
		nReturnValue = SUNSON_Read_Com_String(false, CheckValue);
		if (nReturnValue > 0)
		{
			unsigned char temp[1024] =
			{ 0 };
			hex_asc(CheckValue, temp, nReturnValue);
			sprintf(csLog, "SUNSON_SerialGetCheckValue, CheckValue = %s", temp);
			g_Log.WriteLog(csLog);
		}
		else
		{
			unsigned char ResultInfo[2] =
			{ 0 };
			hex_asc_char(CheckValue[0], ResultInfo);
			sprintf(csLog, "SUNSON_SerialGetCheckValue, ReturnInfo = 0x%c%c(失败)",
					ResultInfo[0], ResultInfo[1]);
			g_Log.WriteLog(csLog);
		}
		return nReturnValue;
	}
	else
	{
		sprintf(csLog, "SUNSON_SerialGetCheckValue, ReturnInfo = 0x%02x(失败)",
				CheckValue[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}

//B.5下载用户密钥

// #define WFS_PIN_USECRYPT     (0x0001)
// #define WFS_PIN_USEFUNCTION  (0x0002)
// #define WFS_PIN_USEMACING    (0x0004)
// #define WFS_PIN_USEKEYENCKEY (0x0020)
 
int SUNSON_SerialLoadUserKey(int ucKeyId, int ucDecryptKeyId, unsigned char KeyAttribute,
		unsigned char ucKeyLen, unsigned char *KeyValue,
		unsigned char *ReturnInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---下载用户密钥---");
	char csLog[1024] =
	{ 0 };
	sprintf(
			csLog,
			"SUNSON_SerialLoadUserKey,KeyId1 = %02x,KeyId2 = %02x,KeyAtt = %02x,keyValueLength = %d",
			ucKeyId, ucDecryptKeyId, KeyAttribute, ucKeyLen);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	if(g_bLogClearSecret == false)
	{
		unsigned char temp[256]={0};
		hex_asc(KeyValue, temp, ucKeyLen);
		sprintf(csLog, "Keyvalue=%s", (char*)temp);
		g_Log.WriteLog(csLog);
	}

	int i = 0;
	int nReturnValue = -1;
	unsigned char CommandData[256];
	memset(CommandData, 0, 256);
	unsigned char data[4];
	memset(data, 0, 4);
	CommandData[0] = 0x1b;
	CommandData[1] = 0x4c;
	CommandData[2] = 0x4b;
	CommandData[3] = 0x00;
	CommandData[4] = 0x16;
	CommandData[5] = ucKeyId / 256;
	CommandData[6] = ucKeyId % 256;
	CommandData[7] = ucDecryptKeyId / 256;
	CommandData[8] = ucDecryptKeyId % 256;
	CommandData[9]=KeyAttribute;
	if (ucKeyLen == 8)
	{
		for (int m = 0; m < 2; m++)
		{
			for (i = 0; i < 8; i++)
			{
				CommandData[10 + i + m * 8] = KeyValue[i];
			}
		}
		ucKeyLen = 16;
	}
	else if (ucKeyLen == 16)
	{
		for (i = 0; i < 16; i++)
		{
			CommandData[10 + i] = KeyValue[i];
		}
	}
	else if (ucKeyLen == 24)
	{
		for (i = 0; i < 24; i++)
		{
			CommandData[10 + i] = KeyValue[i];
		}
	}
	else
		return 0;

	CommandData[3] = (ucKeyLen+6)/256;
	CommandData[4] = (ucKeyLen+6)%256;

	for(i=0;i<(10+ucKeyLen);i++)
		CommandData[10+ucKeyLen]^=CommandData[i];
	CommandData[11+ucKeyLen]=0x0d;
	CommandData[12+ucKeyLen]=0x0a;
	i = SUNSON_SendDataToCom(CommandData, 13+ucKeyLen);
	if (i == 13+ucKeyLen)
	{
		nReturnValue = SUNSON_ReturnST(ReturnInfo);
		if (nReturnValue == 1)
		{
			g_Log.WriteLog("SUNSON_SerialLoadUserKey,success!");
		}
		else
		{
			sprintf(csLog, "SUNSON_SerialLoadUserKey,failure! errorinfo = 0x%02x",
					ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		return nReturnValue;
	}
	else
	{
		sprintf(csLog, "SUNSON_SerialLoadUserKey,failure! errorinfo = 0x%02x",
				ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}



//B.6删除所有密钥
int SUNSON_SerialDeleteAllKeys(unsigned char *ReturnInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---删除所有密钥---");
	char csLog[1024] =
	{ 0 };
	sprintf(csLog, "SUNSON_DeleteAllKeys");
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	int i = 0;
	int nReturnValue = -1;
	unsigned char CommandData[8] =
	{ 0x1b, 0x44, 0x41, 0x00, 0x01, 0x00, 0x0d, 0x0a };
	for (i = 0; i < 5; i++)
		CommandData[5] ^= CommandData[i];
	i = SUNSON_SendDataToCom(CommandData, 8);
	if (i == 8)
	{
		sleep(3);
		nReturnValue = SUNSON_ReturnST(ReturnInfo);
		if (nReturnValue == 1)
		{
			g_Log.WriteLog("SUNSON_SerialDeleteAllKeys,success!");
		}
		else
		{
			sprintf(csLog, "SUNSON_SerialDeleteAllKeys,failure! errorinfo = 0x%02x",
					ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		return nReturnValue;
	}
	else
	{
		sprintf(csLog, "SUNSON_SerialDeleteAllKeys,failure! errorinfo = 0x%02x",
				ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}
//B.7删除指定用户密钥
int SUNSON_SerialDelSpecialUserKey(int UserKeyId, unsigned char *ReturnInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---删除指定用户密钥---");
	char csLog[1024] =
	{ 0 };
	sprintf(csLog, "SUNSON_SerialDelSpecialUserKey,UserKeyId = %d", UserKeyId);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	int i = 0;
	int nReturnValue = -1;
	unsigned char CommandData[10] =
	{ 0x1b, 0x44, 0x44, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0d, 0x0a };
	CommandData[5] = UserKeyId / 256;
	CommandData[6] = UserKeyId % 256;
	for (i = 0; i < 7; i++)
		CommandData[7] ^= CommandData[i];
	i = SUNSON_SendDataToCom(CommandData, 10);
	if (i == 10)
	{
		nReturnValue = SUNSON_ReturnST(ReturnInfo);
		if (nReturnValue == 1)
		{
			g_Log.WriteLog("SUNSON_SerialDelSpecialUserKey,success!");
		}
		else
		{
			sprintf(csLog,
					"SUNSON_SerialDelSpecialUserKey,failure! errorinfo = 0x%02x",
					ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		return nReturnValue;
	}
	else
	{
		sprintf(csLog, "SUNSON_SerialDelSpecialUserKey,failure! errorinfo = 0x%02x",
				ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}

//B.8蜂鸣器使能
int SUNSON_SerialSetBuzzerEnabled(unsigned char ucBuzzerStatus,
							unsigned char *ReturnInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---蜂鸣器使能---");
	char csLog[1024] =
	{ 0 };
	sprintf(csLog, "SUNSON_SerialSetBuzzerEnabled,beep = %02x", ucBuzzerStatus);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	int i = 0;
	int nReturnValue = -1;
	unsigned char CommandData[9] =
	{ 0x1b, 0x53, 0x5a, 0x00, 0x02, 0x00, 0x00, 0x0d, 0x0a };
	CommandData[5] = ucBuzzerStatus;
	for (i = 0; i < 6; i++)
		CommandData[6] ^= CommandData[i];
	i = SUNSON_SendDataToCom(CommandData, 9);
	if (i == 9)
	{
		nReturnValue = SUNSON_ReturnST(ReturnInfo);
		if (nReturnValue == 1)
		{
			g_Log.WriteLog("SUNSON_SerialSetBuzzerEnabled,success!");
		}
		else
		{
			sprintf(csLog,
				"SUNSON_SerialSetBuzzerEnabled,failure! errorinfo = 0x%02x",
				ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		return nReturnValue;
	}
	else
	{
		sprintf(csLog, "SUNSON_SerialSetBuzzerEnabled,failure! errorinfo = 0x%02x",
			ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}
//B.9 设定初始向量
int SUNSON_SerialSetStartValue(unsigned char *StartValue, unsigned char *ReturnInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---设定初始向量---");
	char csLog[1024] =
	{ 0 };
	unsigned char temp[1024] =
	{ 0 };
	hex_asc(StartValue, temp, 8);
	sprintf(csLog, "SUNSON_SerialSetStartValue,vector = %s", temp);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	unsigned char CommandData[16];
	memset(CommandData, 0, 16);
	int nReturnValue = -1;
	CommandData[0] = 0x1b;
	CommandData[1] = 0x44;
	CommandData[2] = 0x56;
	CommandData[3] = 0x00;
	CommandData[4] = 0x09;
	for (int i = 0; i < 8; i++)
		CommandData[5 + i] = StartValue[i];
	for (int i = 0; i < 13; i++)
		CommandData[13] ^= CommandData[i];
	CommandData[14] = 0x0d;
	CommandData[15] = 0x0a;
	int i = SUNSON_SendDataToCom(CommandData, 16);
	if (i == 16)
	{
		nReturnValue = SUNSON_ReturnST(ReturnInfo);
		if (nReturnValue == 1)
		{
			g_Log.WriteLog("SUNSON_SerialSetStartValue,success!");
		}
		else
		{
			sprintf(csLog, "SUNSON_SerialSetStartValue,failure! errorinfo = 0x%02x",
					ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		return nReturnValue;
	}
	else
	{
		sprintf(csLog, "SUNSON_SerialSetStartValue,failure! errorinfo = 0x%02x",
				ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		return 0;

	}
}

int SUNSON_SerialSetStartValueEx(int nDataLen,unsigned char *StartValue,unsigned char *ReturnInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---设定初始向量Ex---");
	char csLog[1024] = {0};
	char temp[1024] = {0};
	hex_asc(StartValue, (unsigned char*)temp, nDataLen);
	sprintf(csLog,"SUNSON_SerialSetStartValueEx,nlen = %d,vector = %s", nDataLen,temp);
	if(g_bLogClearSecret == false)
		g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	unsigned char CommandData[256];
	memset(CommandData,0,256);
	int nReturnValue=-1;
	CommandData[0]=0x1b;
	CommandData[1]=0x44;
	CommandData[2]=0x56;
	CommandData[3]=0x00;
	CommandData[4]=0x01+nDataLen;
	for(int i=0;i<nDataLen;i++)
		CommandData[5+i]=StartValue[i];
	for(int i=0;i<5+nDataLen;i++)
		CommandData[5+nDataLen]^=CommandData[i];
	CommandData[6+nDataLen]=0x0d;   
	CommandData[7+nDataLen]=0x0a;

	int i=SUNSON_SendDataToCom(CommandData,8+nDataLen);
	if(i==8+nDataLen)
	{
		nReturnValue=SUNSON_ReturnST(ReturnInfo);
		if (nReturnValue ==1)
		{
			g_Log.WriteLog("SUNSON_SerialSetStartValueEx,success!");
		}
		else
		{
			sprintf(csLog,"SUNSON_SerialSetStartValueEx,failure! errorinfo = 0x%02x",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		return nReturnValue;			
	}
	else
	{
		sprintf(csLog,"SUNSON_SerialSetStartValueEx,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}

//B.10数据运算
 //JM_mode
 //#define WFS_PIN_MODEENCRYPT (1)
 //#define WFS_PIN_MODEDECRYPT (2)
 //////////////////////////////////
// SF_mode
 //#define WFS_PIN_CRYPTDESECB (0x0001)
// #define WFS_PIN_CRYPTDESCBC (0x0002)
// #define WFS_PIN_CRYPTDESCFB (0x0004)
// #define WFS_PIN_CRYPTRSA    (0x0008)
// #define WFS_PIN_CRYPTECMA   (0x0010)
// #define WFS_PIN_CRYPTDESMAC (0x0020)
// #define WFS_PIN_CRYPTTRIDESECB (0x0040)
// #define WFS_PIN_CRYPTTRIDESCBC (0x0080)
// #define WFS_PIN_CRYPTTRIDESCFB (0x0100)
// #define WFS_PIN_CRYPTTRIDESMAC (0x0200)
// #define WFS_PIN_CRYPTMAAMAC    (0x0400)
 ////////////////////////////////////////
int SUNSON_SerialDataCompute(int KeyId, unsigned char JM_mode, unsigned char SF_mode,
		unsigned char padchar, int datalen, unsigned char *data,
		unsigned char *DataResult)
{
	CCriticalSection autoSc;
	int i = 0;
	g_Log.WriteLog("---数据运算---");
	char csLog[20000] =
	{ 0 };
	unsigned char temp[12000] =
	{ 0 };
	if(datalen > 1024*5)
	{
		g_Log.WriteLog("Data数据超出5K限制!");
		return 0;
	}
	hex_asc(data, temp, datalen);
	
	//兼容F35的调用，如果按照F35参数传，则做个转换
	if(JM_mode == 0x01)
		{
			JM_mode = 0x31; //数据加密
		}
	else if(JM_mode == 0x02)
		{
			JM_mode = 0x30; //数据解密
		}
		
	if(SF_mode == 0x01)
		{
			SF_mode = 0x32; //ECB DES
		}
	else if(SF_mode == 0x02)
		{
			SF_mode = 0x33; //CBC DES
		}
	else if(SF_mode == 0x40)
		{
			SF_mode = 0x30; //ECB 3DES
		}
	else if(SF_mode == 0x80)
		{
			SF_mode = 0x31; //CBC 3DES
		}
	
	hex_asc(data, temp, datalen);
	sprintf(
			csLog,
			"SUNSON_SerialDataCompute, KeyId = %d,JM_mode, = %02x,SF_mode = %02x,padchar = %02x,datalen = %d",
			KeyId, JM_mode, SF_mode, padchar, datalen);
	g_Log.WriteLog(csLog);
	*DataResult = 0x00;
	if(g_bLogClearSecret == false)
	{
		sprintf(csLog,"data = %s",temp);
		g_Log.WriteLog(csLog);	
	}

	unsigned char *CommandData=new unsigned char[datalen+15];
	memset(CommandData,0,datalen+15);
	int nReturnValue=-1;
	CommandData[0]=0x1b;
	CommandData[1]=0x44;
	CommandData[2]=0x4f;
	CommandData[3]=(datalen+8)/256;
	CommandData[4]=(datalen+8)%256;
	CommandData[5]=KeyId/256;
	CommandData[6]=KeyId%256;
	CommandData[7]=JM_mode;
	CommandData[8]=SF_mode;
	CommandData[9]=padchar;
	CommandData[10]=datalen/256;
	CommandData[11]=datalen%256;
	for(int i=0;i<datalen;i++)
		CommandData[12+i]=data[i];
	int templen=12+datalen;
	for(i=0;i<templen;i++)
		CommandData[templen]^=CommandData[i];	
	CommandData[13+datalen]=0x0d;
	CommandData[14+datalen]=0x0a;
	i = SUNSON_SendDataToCom(CommandData, 15 + datalen);
	if (i == (15 + datalen))
	{
		nReturnValue = SUNSON_Read_Com_String(true, DataResult);
		if (nReturnValue > 0)
		{
			unsigned char temp[12000] =
			{ 0 };
			hex_asc(DataResult, temp, nReturnValue);
			if(g_bLogClearSecret == false)
				sprintf(csLog, "SUNSON_SerialDataCompute, DataResult = %s", temp);
			else
				strcpy(csLog, "SUNSON_SerialDataCompute success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			unsigned char ResultInfo[2] =
			{ 0 };
			hex_asc_char(DataResult[0], ResultInfo);
			sprintf(csLog, "SUNSON_SerialDataCompute, ReturnInfo = 0x%c%c(失败)",
					ResultInfo[0], ResultInfo[1]);
			g_Log.WriteLog(csLog);
		}
		delete[] CommandData;
		CommandData = NULL;
		return nReturnValue;
	}
	else
	{
		sprintf(csLog, "SUNSON_SerialDataCompute, ReturnInfo = 0x%02x(失败)",
				DataResult[0]);
		g_Log.WriteLog(csLog);
		delete[] CommandData;
		CommandData = NULL;
		return 0;
	}
}

//B.11取PIN操作
int SUNSON_SerialGetPin(unsigned char ucPinMinLen, unsigned char ucPinMaxLen,
		unsigned char AutoReturnFlag, unsigned char *ReturnInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---取PIN操作---");
	char csLog[1024] =
	{ 0 };
	sprintf(
			csLog,
			"SUNSON_SerialGetPin, PinMinLen = %d,PinMaxLen, = %d,AutoReturnFlag = %02x",
			ucPinMinLen, ucPinMaxLen, AutoReturnFlag);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	int i = 0;
	int nReturnValue = -1;
	unsigned char CommandData[12] =
	{ 0x1b, 0x52, 0x50, 0x00, 0x05, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x0d, 0x0a };
	//if (ucPinMaxLen == 0 || ucPinMaxLen > 12)
	//	ucPinMaxLen = 12;
	CommandData[5] = ucPinMinLen;
	CommandData[6] = ucPinMaxLen;
	CommandData[7] = AutoReturnFlag;
	for (i = 0; i < 9; i++)
		CommandData[9] ^= CommandData[i];
	i = SUNSON_SendDataToCom(CommandData, 12);
	if (i == 12)
	{
		nReturnValue = SUNSON_ReturnST(ReturnInfo);
		if (nReturnValue == 1)
		{
			g_Log.WriteLog("SUNSON_SerialGetPin,success!");
		}
		else
		{
			sprintf(csLog, "SUNSON_SerialGetPin,failure! errorinfo = 0x%02x",
					ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		return nReturnValue;
	}
	sprintf(csLog, "SUNSON_SerialGetPin,failure! errorinfo = 0x%02x", ReturnInfo[0]);
	g_Log.WriteLog(csLog);
	return 0;
}

//B.12Pinblock运算
int SUNSON_SerialGetPinBlock(int UserKeyId, int JM_mode, unsigned char padchar,
		unsigned char CardLen, unsigned char*CardNo,
		unsigned char*PinBlockResult)
{
	CCriticalSection autoSc;
	int i = 0;
	g_Log.WriteLog("---Pinblock运算---");
	char csLog[1024] =
	{ 0 };
	char temp[1024] =
	{ 0 };
	memcpy(temp, CardNo, CardLen);
	sprintf(
			csLog,
			"SUNSON_SerialGetPinBlock, UserKeyId = %d,JM_mode, = %02x,padchar = %02x,CardLen = %d",
			UserKeyId, JM_mode, padchar, CardLen);
	g_Log.WriteLog(csLog);
	*PinBlockResult = 0x00;
	if(g_bLogClearSecret == false)
	{
		g_Log.WriteLog((char*)CardNo);
	}

	//兼容F35的调用，JM_mode如果传递F35的参数，则做个转换
	if(JM_mode == 0x01)
		{
			JM_mode = 0x34;// IBM3624格式
		}
	else if(JM_mode == 0x02)
		{
			JM_mode = 0X35;// X9.8格式
		}
	else if(JM_mode == 0x04)
		{
			JM_mode = 0x30;// ISO9564格式0 
		}	
	else if(JM_mode == 0x08)
		{
			JM_mode = 0x31;// ISO9564格式1
		}

	if(JM_mode==0x34 ) //IS0格式1,IBM3624
	{
		//if(JM_mode==0x31 || JM_mode==0x34)
		{
			CardLen=12;
			for(int m=0;m<12;m++)
				CardNo[m]=0x00;
		}
	}
	if(JM_mode==0x31)
	{
		if(CardLen>10)
			CardLen=10;
	}

	if(JM_mode==0x30 || JM_mode==0x31||JM_mode==0x33|| JM_mode==0x35)
	{
		if(CardLen!=0)
		{
			if(strlen((char*)CardNo)==0)
			{
				for(int n=0;n<CardLen;n++)
					CardNo[n]=0x00;
			}
		}
	}

	int nCardRealLen = CardLen;
	unsigned char CommandData[26];
	memset(CommandData, 0, 26);
	int nReturnValue = -1;
	CommandData[0] = 0x1b;
	CommandData[1] = 0x50;
	CommandData[2] = 0x42;
	CommandData[3] = 0x00;
	CommandData[4] = 6 + nCardRealLen;
	CommandData[5] = UserKeyId / 256;
	CommandData[6] = UserKeyId % 256;
	CommandData[7] = JM_mode;
	CommandData[8]=padchar,
	CommandData[9] = CardLen;
	for (int i = 0; i < nCardRealLen; i++)
		CommandData[10 + i] = CardNo[i];
	int templen = 10 + nCardRealLen;
	for (i = 0; i < templen; i++)
		CommandData[templen] ^= CommandData[i];
	CommandData[11 + nCardRealLen] = 0x0d;
	CommandData[12 + nCardRealLen] = 0x0a;
	i = SUNSON_SendDataToCom(CommandData, 13 + nCardRealLen);
	if (i == (13 + nCardRealLen))
	{
		nReturnValue = SUNSON_Read_Com_String(false, PinBlockResult);
		if (nReturnValue > 0)
		{
			unsigned char temp[1024] =
			{ 0 };
			hex_asc(PinBlockResult, temp, nReturnValue);
			if(g_bLogClearSecret == false)
				sprintf(csLog, "SUNSON_SerialGetPinBlock, success ,pinblock=%s",(char*)temp);
			else
				sprintf(csLog, "SUNSON_SerialGetPinBlock, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			unsigned char ResultInfo[2] =
			{ 0 };
			hex_asc_char(PinBlockResult[0], ResultInfo);
			sprintf(csLog, "SUNSON_SerialGetPinBlock, ReturnInfo = 0x%c%c(失败)",
					ResultInfo[0], ResultInfo[1]);
			g_Log.WriteLog(csLog);
		}
		return nReturnValue;
	}
	else
	{
		sprintf(csLog, "SUNSON_SerialGetPinBlock, PinBlockResult = 0x%02x(失败)",
				PinBlockResult[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}

int MakeMacSerial(int UserKeyId,int Mac_mode,int nMacDataLen,unsigned char *ucMacData,unsigned char *MacResult)
{
	char csLog[20000] = {0};
	sprintf(csLog,"MakeMacSerial, UserKeyId = %d,Mac_mode = %02x,nMacDataLen = %d,",UserKeyId,Mac_mode,nMacDataLen);
	g_Log.WriteLog(csLog);

	if(g_bLogClearSecret == false)
	{
		unsigned char temp[12000] = {0};
		hex_asc(ucMacData,temp,nMacDataLen);
		sprintf(csLog,"MacDataBlock= %s",temp);
		g_Log.WriteLog(csLog);
	}
	*MacResult = 0x00;

	int i=0;
	unsigned char CommandData[10000];
	memset(CommandData,0,10000);
	int nReturnValue=-1;
	CommandData[0]=0x1b;
	CommandData[1]=0x4d;
	CommandData[2]=0x43;
	CommandData[3]=(nMacDataLen+6)/256;
	CommandData[4]=(nMacDataLen+6)%256;
	CommandData[5]=UserKeyId/256;
	CommandData[6]=UserKeyId%256;	
	CommandData[7]=Mac_mode;
	CommandData[8]=nMacDataLen/256;
	CommandData[9]=nMacDataLen%256;
	for(i=0;i<nMacDataLen;i++)
		CommandData[10+i]=ucMacData[i];
	int templen=10+nMacDataLen;
	for(i=0;i<templen;i++)
		CommandData[templen]^=CommandData[i];
	CommandData[11+nMacDataLen]=0x0d;
	CommandData[12+nMacDataLen]=0x0a;
	g_Com.ClearTxRx();
	i=SUNSON_SendDataToCom(CommandData,13+nMacDataLen);
	if(i==(13+nMacDataLen))
	{
		nReturnValue=SUNSON_Read_Com_String(true,MacResult);
		if (nReturnValue>0)
		{
			if(g_bLogClearSecret == false)
			{
				unsigned char temp[1024] = {0};
				hex_asc(MacResult,temp,nReturnValue);
				sprintf(csLog,"MakeMacSerial, result = %s",temp);
				g_Log.WriteLog(csLog);
			}
		}
		else
		{
			//unsigned char ResultInfo[2] = {0};
			//ASCII_Hex(MacResult[0],ResultInfo);
			sprintf(csLog,"MakeMacSerial, ReturnInfo = 0x%02x(失败)",MacResult[0]);
			g_Log.WriteLog(csLog);
		}
		return nReturnValue;				
	}
	else
	{
		sprintf(csLog,"MakeMacSerial, send error ReturnInfo = 0x%02x(失败)",MacResult[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}

//B.13MAC运算
// Mac_mode
// #define WFS_PIN_CRYPTDESMAC    (0x0020)
// #define WFS_PIN_CRYPTTRIDESMAC (0x0200)

int SUNSON_SerialMakeMac(int UserKeyId, int Mac_mode, int nMacDataLen,
		unsigned char *ucMacData, unsigned char *MacResult)
{
	CCriticalSection autoSc;
	
	g_Log.WriteLog("---MAC运算---");

	//兼容F35的调用，如果传递F35的参数，则做转换
	if(Mac_mode == 0x20)
		{
			Mac_mode = 0x30; //X9.9
		}
	else if(Mac_mode == 0x21)
		{
			Mac_mode = 0x35; //X9.9T
		}
	else if(Mac_mode == 0x32)
		{
			Mac_mode = 0x32; //UBC
		}	
	else if(Mac_mode == 0x200)
		{
			Mac_mode = 0x33; //X9.19
		}
		
	
	*MacResult = 0x00;

	if(nMacDataLen <= g_MacBlockNum)
	{
		return MakeMacSerial(UserKeyId, Mac_mode, nMacDataLen, ucMacData, MacResult);
	}

	int nDataLine = ((nMacDataLen)%g_MacBlockNum == 0)?((nMacDataLen)/g_MacBlockNum):((nMacDataLen)/g_MacBlockNum + 1); //Mac数据分组

	int nItemLen = 0;
	unsigned char ActiveMacMode = 0x00;
	unsigned char ucMacResult[17];
	unsigned char MacData[6000] = {0};
	int nflag = 0;
	for (int m=0;m<nDataLine;m++)
	{
		memset(ucMacResult,0,17);
		int nlen = (m == (nDataLine - 1))?(nMacDataLen- g_MacBlockNum*m):g_MacBlockNum; //计算每组计算的长度

		if (m != 0)  //不是第一组时要与后面8字节进行异或
		{
			for(int i=0;i<nItemLen;i++)
			{
				ucMacData[i +m*g_MacBlockNum]^=MacData[i];
			}
		}
		for (int i=0; i<nlen; i++)
		{
			MacData[i] = ucMacData[i +m*g_MacBlockNum];
		}
		
		if(Mac_mode == 0x35) //MAA
			ActiveMacMode = 0x35;
		else
			ActiveMacMode = 0x30;

		//最后一组用原始mode
		if(m==nDataLine-1)
			ActiveMacMode = Mac_mode;

		nflag = MakeMacSerial(UserKeyId,ActiveMacMode,nlen,MacData,ucMacResult); //拆分的全部用X9.9算法，在最后一步处理
		if(nflag > 0)
		{
			nItemLen = nflag;
			memcpy(MacData,ucMacResult,nItemLen);
		}
		else
		{
			return 0; //运算失败	
		}
	}
	memcpy(MacResult,ucMacResult,nflag);
	return nflag;
	
}

//B.14使用EPP仿真键盘
int SUNSON_SerialUseEppPlainTextMode(unsigned char PlaintextLength,
							   unsigned char AutoEnd, unsigned char *ReturnInfo)
{
	CCriticalSection autoSc;
	int i = 0;
	g_Log.WriteLog("---使用EPP仿真键盘---");
	char csLog[1024] =
	{ 0 };
	sprintf(csLog,
		"SUNSON_SerialUseEppPlainTextMode, PlaintextLength = %d,AutoEnd = %02x",
		PlaintextLength, AutoEnd);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	int nReturnValue = -1;
	unsigned char CommandData[10] =
	{ 0x1b, 'O', 'K', 0x00, 0x03, 0x00, 0x00, 0x00, 0x0d, 0x0a };
	CommandData[5] = PlaintextLength;
	CommandData[6] = AutoEnd;
	for (i = 0; i < 7; i++)
		CommandData[7] ^= CommandData[i];
	i = SUNSON_SendDataToCom(CommandData, 10);
	if (i == 10)
	{
		nReturnValue = SUNSON_ReturnST(ReturnInfo);
		if (nReturnValue == 1)
		{
			g_Log.WriteLog("SUNSON_SerialUseEppPlainTextMode,success!");
		}
		else
		{
			sprintf(csLog,
				"SUNSON_SerialUseEppPlainTextMode,failure! errorinfo = 0x%02x",
				ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		return nReturnValue;
	}
	else
	{
		sprintf(csLog,
			"SUNSON_SerialUseEppPlainTextMode,failure! errorinfo = 0x%02x",
			ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}

//B.15关闭EPP仿真键盘
int SUNSON_SerialCloseEppPlainTextMode(unsigned char *ReturnInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---使用EPP仿真键盘---");
	g_Log.WriteLog("SUNSON_SerialCloseEppPlainTextMode");
	char csLog[1024] =
	{ 0 };
	*ReturnInfo = 0x00;

	int nReturnValue = -1;
	unsigned char CommandData[8] =
	{ 0x1b, 'C', 'K', 0x00, 0x01, 0x12, 0x0d, 0x0a };
	int i = SUNSON_SendDataToCom(CommandData, 8);
	if (i == 8)
	{
		nReturnValue = SUNSON_ReturnST(ReturnInfo);
		if (nReturnValue == 1)
		{
			g_Log.WriteLog("SUNSON_SerialCloseEppPlainTextMode,success!");
		}
		else
		{
			sprintf(csLog,
					"SUNSON_SerialCloseEppPlainTextMode,failure! errorinfo = 0x%02x",
					ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		return nReturnValue;
	}
	else
	{
		sprintf(csLog,
				"SUNSON_CloseEppPlainTextMode,failure! errorinfo = 0x%02x",
				ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}

}

//B.16  取随机数,成功返回指定随机数长度，失败返回0
int SUNSON_SerialGetRandomData(unsigned char ucRandomDataType,
		unsigned char ucDataLength, unsigned char *ReturnInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---取随机数---");
	char csLog[1024] =
	{ 0 };
	sprintf(csLog,
			"SUNSON_SerialGetRandomData, ucRandomDataType = %02x,ucDataLength = %d",
			ucRandomDataType, ucDataLength);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	int i = 0;
	int nReturnValue = -1;
	unsigned char CommandData[10] =
	{ 0x1b, 0x52, 0x41, 0x00, 0x03, 0x30, 0x00, 0x00, 0x0d, 0x0a };
	CommandData[5] = ucRandomDataType;
	CommandData[6] = ucDataLength;
	for (i = 0; i < 7; i++)
		CommandData[7] ^= CommandData[i];
	i = SUNSON_SendDataToCom(CommandData, 10);
	if (i == 10)
	{
		nReturnValue = SUNSON_Read_Com_String(false, ReturnInfo);
		if (nReturnValue > 0)
		{
			unsigned char temp[1024] =
			{ 0 };
			hex_asc(ReturnInfo, temp, nReturnValue);
			if(g_bLogClearSecret == false)
				sprintf(csLog, "SUNSON_SerialGetRandomData, DataResult = %s", temp);
			else
				sprintf(csLog, "SUNSON_SerialGetRandomData, success");
			
			g_Log.WriteLog(csLog);
		}
		else
		{
			unsigned char ResultInfo[2] =
			{ 0 };
			hex_asc_char(ReturnInfo[0], ResultInfo);
			sprintf(csLog, "SUNSON_SerialGetRandomData, ReturnInfo = 0x%c%c(失败)",
					ResultInfo[0], ResultInfo[1]);
			g_Log.WriteLog(csLog);
		}
		return nReturnValue;
	}
	else
	{
		sprintf(csLog, "SUNSON_SerialGetRandomData, ReturnInfo = 0x%02x(失败)",
				ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}

//2012-6-15  add by xiaweiqian
//UBC mac  支持2K数据   macdata 传ASCII字符串
int SUNSON_SerialMakeUBCMac(int UserKeyId,int nMacLen,unsigned char* macdata,unsigned char *ReturnInfo)
{
	g_Log.WriteLog("---UBC算法mac---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SerialMakeUBCMac, nMacLen = %d,UserKeyId = %d",nMacLen,UserKeyId);
	g_Log.WriteLog(csLog);

	int nDataLine=0; //Mac数据长度
	if (nMacLen%8==0)
	{
		nDataLine=nMacLen/8;
	}
	else
	{
		nDataLine=(nMacLen/8+1);
	}

	int nRealMacDataLen=nDataLine*8;
	unsigned char *ucRealMacData = new unsigned char[nRealMacDataLen];
	memset(ucRealMacData,0,nRealMacDataLen);//Mac数据填充

	for (int m=0;m<nMacLen;m++)
	{
		ucRealMacData[m] = macdata[m];
	}

	unsigned char ucXorData[8];
	memset(ucXorData,0,8);
	int i=-1;
	//8字节Mac数据，无需异或
	if (nDataLine==1)
	{
		for (i=0;i<8;i++)
		{
			ucXorData[i]=ucRealMacData[i];
		}
	}
	else 
		if (nDataLine>=2) //Mac数据长度大于16字节
		{
			for (i=0;i<8;i++) //先将前16字节依次异或
			{
				ucXorData[i]=ucRealMacData[i]^ucRealMacData[i+8];
			}

			if (nDataLine>2) //将前16个字节的异或值与后续的每8个字节做异或
			{
				for(int k=2;k<nDataLine;k++)
				{
					for(i=0;i<8;i++)
						ucXorData[i]^=ucRealMacData[i+k*8];

				}		
			}
		}
		//将异或值按ASCII拆分，1位变两位
		unsigned char ucHexMacData[16];
		memset(ucHexMacData,0,16);
		hex_asc(ucXorData,ucHexMacData,8);

		unsigned char ucQianHexData[8]; //异或值前八个字节
		memset(ucQianHexData,0,8);
		unsigned char ucHouHexData[8];  //异或值后八个字节
		memset(ucHouHexData,0,8);

		for (i=0;i<8;i++)
		{
			ucQianHexData[i]=ucHexMacData[i];
			ucHouHexData[i]=ucHexMacData[i+8];
		}

		unsigned char ucFirstData[16];  //前八字节数据做ＤＥＳ运算结果
		memset(ucFirstData,0,16);

		unsigned char nEncryDataLen=8;
		int nEncryDataResult = SUNSON_SerialMakeMac(UserKeyId,0x30,nEncryDataLen,ucQianHexData,ucFirstData);


		unsigned char ucFirstXorData[8]; // 存储前8字节加密结果与后八字节异或运算的结果
		memset(ucFirstXorData,0,8);
		if (nEncryDataResult >=0)
		{
			for (i=0;i<8;i++)
			{
				ucFirstXorData[i]=ucFirstData[i]^ucHouHexData[i];
			}
		}
		else
		{
			delete[] ucRealMacData;
			ucRealMacData=NULL;
			return CMD_FAILS;
		}

		unsigned char ucSecondData[16];  //异或结果做DES运算
		memset(ucSecondData,0,16);	

		nEncryDataResult=SUNSON_SerialMakeMac(UserKeyId,0x30,nEncryDataLen,ucFirstXorData,ucSecondData);
		if (nEncryDataResult>=0)
		{
			unsigned char tempResult[40] = {0};
			unsigned char tempResult1[60] = {0};

			for (i=0;i<8;i++)
			{

				tempResult[i]=ucSecondData[i]; //存储最后的mac结果
			}

			hex_asc(tempResult,tempResult1,8);

			for(i=0; i<8; i++)
			{
				ReturnInfo[i] = tempResult1[i];
			}

			if(g_bLogClearSecret == false)
			{
				g_Log.WriteLog("UBC运算结果：");
				sprintf(csLog,"%s",ReturnInfo);
			}
			else
				sprintf(csLog,"UBC mac success");	
			g_Log.WriteLog(csLog);

			delete[] ucRealMacData;
			ucRealMacData=NULL;

			return nEncryDataResult;
		}
		delete[] ucRealMacData;
		ucRealMacData=NULL;
		return 0;
}

//获取键盘状态  add 20131103 nby,获取初始化状态添加
int SUNSON_SerialGetEppStatus(unsigned char*EppStatus)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---取EPP状态---");
	g_Log.WriteLog("SUNSON_SerialGetEppStatus");
	char csLog[1024] = {0};
	*EppStatus = 0x00;

	int i=0;
	int nReturnValue=-1;
	unsigned char CommandData[8]={0x1b,0x45,0x57,0x00,0x01,0x00,0x0d,0x0a};
	CommandData[5]=CommandData[0]^CommandData[1]^CommandData[2]^CommandData[3]^CommandData[4];

	i=SUNSON_SendDataToCom(CommandData,8);
	if(i==8)
	{
		nReturnValue=SUNSON_Read_Com_String(false,EppStatus);
		if (nReturnValue>0)
		{
			unsigned char temp[1024] = {0};
			hex_asc(EppStatus,temp,nReturnValue);
			sprintf(csLog,"SUNSON_SerialGetEppStatus, DataResult = %s",temp);
			g_Log.WriteLog(csLog);
		}
		else
		{
			unsigned char ResultInfo[2] = {0};
			hex_asc_char(EppStatus[0],ResultInfo);
			sprintf(csLog,"SUNSON_SerialGetEppStatus, ReturnInfo = 0x%c%c(失败)",ResultInfo[0],ResultInfo[1]);
			g_Log.WriteLog(csLog);
		}
		return nReturnValue;		
	}
	else 
	{
		sprintf(csLog,"SUNSON_SerialGetEppStatus, ReturnInfo = 0x%02x(失败)",EppStatus[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}

//设定卡键时间命令
int SUNSON_SerialSetLockKeyTimeOut(unsigned char TimeOut,unsigned char *ReturnInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---设置卡键时间---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SerialSetLockKeyTimeOut,TimeOut= %d",TimeOut);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	int i=0;
	int nReturnValue=-1;
	unsigned char CommandData[10]={0x1b,0x53,0x4A,0x00,0x02,0x00,0x00,0x0d,0x0a};
	CommandData[5]=TimeOut;
	CommandData[6]=CommandData[0]^CommandData[1]^CommandData[2]^CommandData[3]^CommandData[4]^CommandData[5];

	i=SUNSON_SendDataToCom(CommandData,9);
	if(i==9)
	{
		nReturnValue=SUNSON_ReturnST(ReturnInfo);
		if (nReturnValue ==1)
		{
			g_Log.WriteLog("SUNSON_SerialSetLockKeyTimeOut,success!");
		}
		else
		{
			sprintf(csLog,"SUNSON_SerialSetLockKeyTimeOut,failure! errorinfo = 0x%02x",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		return nReturnValue;
	}
	else 
	{
		sprintf(csLog,"SUNSON_SerialSetLockKeyTimeOut,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}

//打开/关闭开封自毁   0x00 关闭固件自毁(仅100N支持)
//                    0x01 开启固件自毁(仅100N支持)
//                    0x02 关闭密钥自毁
//                    0x04 开启密钥自毁
int SUNSON_SerialEnableMoveDestruct(unsigned char mode, unsigned char *ReturnInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("****设置开封自毁****");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SerialEnableMoveDestruct,ucSMMode = 0x%02X",mode);
	g_Log.WriteLog(csLog);
	int i = -1;
	int ST = -1;
	unsigned char command[32] = {0};
	command[0] = 0x1b;
	command[1] = 0x54;
	command[2] = 0x32;
	command[3] = 0x00;
	command[4] = 0x02;
	command[5] = mode;

	for(i=0;i<6;i++)
		command[6]^=command[i];

	command[7] = 0x0d;
	command[8] = 0x0a;

	i = SUNSON_SendDataToCom(command,9);
	if(9 == i)
	{
		ST = SUNSON_ReturnST(ReturnInfo); 
		if (1 == ST)
		{
			g_Log.WriteLog("SUNSON_SerialEnableMoveDestruct打开自毁设置成功！");
		}
		else
			g_Log.WriteLog("SUNSON_SerialEnableMoveDestruct打开自毁设置失败！");
		return ST;
	}
	else
		return 0;
}

//设置国密非国密模式
int SUNSON_SerialSetEPPSMMode(unsigned char ucSMMode)
{
	g_Log.WriteLog("****设置国密非国密模式****");
	CCriticalSection autoSc;

	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SerialSetEPPSMMode,ucSMMode = 0x%02X",ucSMMode);
	g_Log.WriteLog(csLog);
	int i = -1;
	int ST = -1;
	unsigned char ReturnInfo[32] = {0};
	unsigned char command[32] = {0};
	command[0] = 0x1b;
	command[1] = 0x53;
	command[2] = 0x57;
	command[3] = 0x00;
	command[4] = 0x02;
	command[5] = ucSMMode;

	for(i=0;i<6;i++)
		command[6]^=command[i];

	command[7] = 0x0d;
	command[8] = 0x0a;
	i = SUNSON_SendDataToCom(command,9);
	if(9 == i)
	{
		ST = SUNSON_ReturnST(ReturnInfo);
		if (1 == ST)
		{
			switch (ucSMMode)
			{
			case  0x00: // 非国密模式
				g_bSMmode = false;
				g_Log.WriteLog("SUNSON_SerialSetEPPSMMode非国密模式设置成功！");
				break;
			case 0x01: // 国密模式
				g_bSMmode = true;
				g_Log.WriteLog("SUNSON_SerialSetEPPSMMode国密模式设置成功！");
				break;
			default:break;
			}
		}
		else
			g_Log.WriteLog("SUNSON_SerialSetEPPSMMode模式设置失败！");
		return ST;
	}
	else
		return 0;
}

//获取键盘模式 国密 非国密
int SUNSON_SerialGetEPPSMMode(unsigned char *ucEPPMode)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("****获取键盘模式****");
	char csLog[1024] = {0};
	int i = -1;
	int ST = -1;
	unsigned char command[32] = {0};
	command[0] = 0x1b;
	command[1] = 0x47;
	command[2] = 0x57;
	command[3] = 0x00;
	command[4] = 0x02;
	command[5] = 0x91;

	for(i=0;i<6;i++)
		command[6]^=command[i];

	command[7] = 0x0d;
	command[8] = 0x0a;
	i = SUNSON_SendDataToCom(command,9);
	if(9 == i)
	{
		ST = SUNSON_ReturnST(ucEPPMode);
		sprintf(csLog,"SUNSON_SerialGetEPPSMMode,ucEPPMode = %02X",ucEPPMode[0]);
		g_Log.WriteLog(csLog);
		if(ST == 1)
		{
			if(ucEPPMode[0] == 0x00)
			{
				g_bSMmode = false;
			}
			else if(ucEPPMode[0] == 0x01)
			{
				g_bSMmode = true;
			}
			g_Log.WriteLog("获取键盘模式成功！");
		}
		else
			g_Log.WriteLog("获取键盘模式失败！");
		return ST;
	}
	else
		return 0;
}
//生成SM2密钥
int SUNSON_SerialGenerateSM2Key(int ucKeyId,int KeyAtt,unsigned char *ReturnInfo)
{
	KeyAtt = 0x0F;
	CCriticalSection autoSc;
	g_Log.WriteLog("---生成SM2密钥---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SerialGenerateSM2Key, ucKeyId = %d, KeyAtt=0x%02X",ucKeyId,KeyAtt);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;
	int i=0;
	int nReturnValue=-1;

	unsigned char CommandData[255] = {0};
	CommandData[0] = 0x1b;
	CommandData[1] = 0x47;
	CommandData[2] = 0x4d;
	CommandData[3] = 0x00;
	CommandData[4] = 0x04;
	CommandData[5] = ucKeyId/256;
	CommandData[6] = ucKeyId%256;
	CommandData[7] = KeyAtt;

	for(i=0; i<8; i++)
		CommandData[8]^=CommandData[i];

	CommandData[9]=0x0d;
	CommandData[10]=0x0a;
	i = SUNSON_SendDataToCom(CommandData,11);
	if(i==11)
	{
		nReturnValue=SUNSON_ReturnST(ReturnInfo);
		if (nReturnValue ==1)
		{
			g_Log.WriteLog("SUNSON_SerialGenerateSM2Key,success!");
		}
		else
		{
			sprintf(csLog,"SUNSON_SerialGenerateSM2Key,failure! errorinfo = 0x%x",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
			return 0;
		}
		return nReturnValue;
	}
	else
	{
		sprintf(csLog,"SUNSON_SerialGenerateSM2Key,failure! errorinfo = 0x%x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}

//下载SM2密钥
int SUNSON_SerialLoadSM2Key(int ucKeyId,int KeyAtt,int nKeylen,unsigned char *KeyValue,unsigned char *ReturnInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---下载SM2密钥---");
	char csLog[1024] = {0};
	unsigned char HexKeyData[1024] = {0};
	hex_asc(KeyValue,HexKeyData,nKeylen);
	sprintf(csLog,"SUNSON_SerialLoadSM2Key,ucKeyId = %02x,KeyAtt = 0x%02x,nKeylen = %d",ucKeyId,KeyAtt,nKeylen);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;
	if(g_bLogClearSecret == false)
	{
		sprintf(csLog,"HexKeyData = %s",HexKeyData);
		g_Log.WriteLog(csLog);		
	}

	int i=0;
	int nReturnValue=-1;
	unsigned char CommandData[255];
	memset(CommandData,0,255);
	unsigned char data[4];
	memset(data,0,4);
	CommandData[0] = 0x1b;
	CommandData[1] = 0x4c;
	CommandData[2] = 0x53;
	CommandData[3] = (5+nKeylen)/256;
	CommandData[4] = (5+nKeylen)%256;
	CommandData[5] = nKeylen;
	CommandData[6] = ucKeyId/256;
	CommandData[7] = ucKeyId%256;
	CommandData[8] = KeyAtt;

	for(i=0;i<nKeylen;i++)
	{
		CommandData[9+i]=KeyValue[i];
	}

	for(i=0;i< (9+nKeylen) ;i++)
		CommandData[9+nKeylen]^=CommandData[i];

	CommandData[10+nKeylen] = 0x0d;
	CommandData[11+nKeylen] = 0x0a;

	i=SUNSON_SendDataToCom(CommandData,12+nKeylen);
	if(i==12+nKeylen)
	{
		nReturnValue=SUNSON_ReturnST(ReturnInfo);
		if (nReturnValue ==1)
		{
			g_Log.WriteLog("SUNSON_SerialLoadSM2Key,success!");
		}
		else
		{
			sprintf(csLog,"SUNSON_SerialLoadSM2Key,failure! errorinfo = 0x%02x",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		return nReturnValue;
	}
	else
	{
		sprintf(csLog,"SUNSON_SerialLoadSM2Key,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}

//导出SM2公钥
int SUNSON_SerialExportSM2PublicKey(int ucKeyId,unsigned char *SM2PKeyValue)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---导出SM2公钥---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SerialExportSM2PublicKey, ucKeyId = %d",ucKeyId);
	g_Log.WriteLog(csLog);
	*SM2PKeyValue = 0x00;
	int i=0;
	int nReturnValue=-1;
	unsigned char CommandData[255] = {0};
	CommandData[0] = 0x1b;
	CommandData[1] = 0x45;
	CommandData[2] = 0x4d;
	CommandData[3] = 0x00;
	CommandData[4] = 0x04;
	CommandData[5] = ucKeyId/256;
	CommandData[6] = ucKeyId%256;
	CommandData[7] = 0x50;

	for(i=0; i<8; i++)
		CommandData[8]^=CommandData[i];

	CommandData[9]=0x0d;
	CommandData[10]=0x0a;

	i = SUNSON_SendDataToCom(CommandData,11);
	if(11 == i)
	{
		nReturnValue = SUNSON_Read_Com_String(false,SM2PKeyValue);
		if (nReturnValue > 0)
		{
			unsigned char temp[1024] = {0};
			hex_asc(SM2PKeyValue,temp,nReturnValue);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_SerialExportSM2PublicKey, keyValue = %s",temp);
			else
				sprintf(csLog,"SUNSON_SerialExportSM2PublicKey, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			unsigned char ResultInfo[2] = {0};
			hex_asc_char(SM2PKeyValue[0],ResultInfo);
			sprintf(csLog,"SUNSON_SerialExportSM2PublicKey, ReturnInfo = 0x%c%c(失败)",ResultInfo[0],ResultInfo[1]);
			g_Log.WriteLog(csLog);
		}
		return nReturnValue;
	}
	else
	{
		sprintf(csLog,"SUNSON_SerialExportSM2PublicKey, ReturnInfo = 0x%02x(失败)",SM2PKeyValue[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}

//Hash ID初始化
int SUNSON_SerialInitHashID(int ucKeyId,unsigned char UserIDLen,unsigned char *UserID,unsigned char *ReturnInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---Hash ID初始化---");
	char csLog[1024] = {0};
	unsigned char HexUserID[1024] = {0};
	hex_asc(UserID,HexUserID,UserIDLen);
	sprintf(csLog,"SUNSON_SerialInitHashID, ucKeyId = %d,UserIDLen = %d,userid=0x%s",ucKeyId,UserIDLen,(char*)HexUserID);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;
	if(g_bLogClearSecret == false)
	{
		sprintf(csLog,"HexUserID = %s",HexUserID);
		g_Log.WriteLog(csLog);
	}

	int i=0;
	int nReturnValue=-1;
	unsigned char *CommandData=new unsigned char[UserIDLen+255];
	memset(CommandData,0,UserIDLen+255);
	CommandData[0] = 0x1b;
	CommandData[1] = 0x47;
	CommandData[2] = 0x49;
	CommandData[3] = (UserIDLen+4)/256;
	CommandData[4] = (UserIDLen+4)%256;
	CommandData[5] = ucKeyId/256;
	CommandData[6] = ucKeyId%256;
	CommandData[7] = UserIDLen;

	for (i = 0; i < UserIDLen; i++)
	{
		CommandData[8+i] = UserID[i];
	}

	for(i=0; i < (8+UserIDLen); i++)
		CommandData[8+UserIDLen]^=CommandData[i];

	CommandData[9 + UserIDLen ]=0x0d;
	CommandData[10 + UserIDLen]=0x0a;

	i = SUNSON_SendDataToCom(CommandData,11 +UserIDLen);
	if((11 + UserIDLen)  == i)
	{
		nReturnValue = SUNSON_Read_Com_String(false,ReturnInfo);
		if (nReturnValue > 0)
		{
			//unsigned char temp[1024] = {0};
			//hex_asc(ReturnInfo,temp,nReturnValue);
			sprintf(csLog,"SUNSON_SerialInitHashID, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			unsigned char ResultInfo[2] = {0};
			hex_asc_char(ReturnInfo[0],ResultInfo);
			sprintf(csLog,"SUNSON_SerialInitHashID, ReturnInfo = 0x%c%c(失败)",ResultInfo[0],ResultInfo[1]);
			g_Log.WriteLog(csLog);
		}
		delete [] CommandData;
		CommandData=NULL;
		return nReturnValue;
	}
	else
	{
		sprintf(csLog,"SUNSON_SerialInitHashID, ReturnInfo = 0x%02x(失败)",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		delete [] CommandData;
		CommandData=NULL;
		return 0;
	}
}

//SM2签名
int SUNSON_SerialGetSM2SignatureEX(int ucKeyId,unsigned char EDataLen,unsigned char *EData,unsigned char *ReturnInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---获取SM2签名---");
	char csLog[1024] = {0};
	unsigned char HexEData[1024] = {0};
	hex_asc(EData,HexEData,EDataLen);
	sprintf(csLog,"SUNSON_SerialGetSM2SignatureEX, ucKeyId = %d,EDataLen = %d",ucKeyId,EDataLen);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;
	if(g_bLogClearSecret == false)
	{
		sprintf(csLog,"HexEData = %s",HexEData);
		g_Log.WriteLog(csLog);
	}

	int i=0;
	int nReturnValue=-1;

	unsigned char *CommandData=new unsigned char[EDataLen+255];
	memset(CommandData,0,EDataLen+255);
	CommandData[0] = 0x1b;
	CommandData[1] = 0x47;
	CommandData[2] = 0x51;
	CommandData[3] = (EDataLen+4)/256;
	CommandData[4] = (EDataLen+4)%256;
	CommandData[5] = ucKeyId/256;
	CommandData[6] = ucKeyId%256;
	CommandData[7] = EDataLen;

	for (i = 0; i < EDataLen; i++)
	{
		CommandData[8+i] = EData[i];
	}

	for(i=0; i < (8+EDataLen); i++)
		CommandData[8+EDataLen]^=CommandData[i];

	CommandData[9 + EDataLen]=0x0d;
	CommandData[10 + EDataLen]=0x0a;

	i = SUNSON_SendDataToCom(CommandData,11 +EDataLen);
	if((11 + EDataLen)  == i)
	{
		nReturnValue = SUNSON_Read_Com_String(false,ReturnInfo);
		if (nReturnValue > 0)
		{
			unsigned char temp[1024] = {0};
			hex_asc(ReturnInfo,temp,nReturnValue);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_SerialGetSM2SignatureEX, ReturnInfo = %s",temp);
			else
				sprintf(csLog,"SUNSON_SerialGetSM2SignatureEX, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			unsigned char ResultInfo[2] = {0};
			hex_asc_char(ReturnInfo[0],ResultInfo);
			sprintf(csLog,"SUNSON_SerialGetSM2SignatureEX, ReturnInfo = 0x%c%c(失败)",ResultInfo[0],ResultInfo[1]);
			g_Log.WriteLog(csLog);
		}
		delete [] CommandData;
		CommandData=NULL;
		return nReturnValue;
	}
	else
	{
		sprintf(csLog,"SUNSON_SerialGetSM2SignatureEX, ReturnInfo = 0x%02x(失败)",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		delete [] CommandData;
		CommandData=NULL;
		return 0;
	}
}

////1.39 SM2签名,兼容F35接口，OpenFlag忽略
int SUNSON_SerialGetSM2Signature(int ucKeyId,unsigned char OpenFlag,
		int EDataLen,unsigned char *EData,unsigned char *ReturnInfo)
{
	char csLog[2048] = {0};
	unsigned char HexEData[1024] = {0};
	hex_asc(EData,HexEData,EDataLen);
	sprintf(csLog,"SUNSON_SerialGetSM2Signature, ucKeyId = %d,EDataLen = %d,EData = %s",ucKeyId,EDataLen, (char*)HexEData);
	g_Log.WriteLog(csLog);
	//初始化userid
	SUNSON_InitHashID(ucKeyId, EData[0], EData+1, ReturnInfo);
	//SM3计算E值
	unsigned char ucResult[256]={0};
	int nlen = SUNSON_SM3HashOperateEX(0x06, EDataLen-EData[0]-1, EData+1+EData[0], ucResult);
	return SUNSON_GetSM2SignatureEX(ucKeyId, nlen, ucResult, ReturnInfo);
}

//SM2验签
int SUNSON_SerialVerifySM2SignatureEX(int ucKeyId,unsigned char EDataLen,unsigned char *EData,unsigned char SignatureLen,unsigned char *Signature,unsigned char *ReturnInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---SM2签名验证---");
	char csLog[1024] = {0};
	unsigned char HexEData[1024] = {0};
	hex_asc(EData,HexEData,EDataLen);
	unsigned char HexSignature[1024] = {0};
	hex_asc(Signature,HexSignature,SignatureLen);
	sprintf(csLog,"SUNSON_SerialVerifySM2SignatureEX, ucKeyId = %d,EDataLen = %d,SignatureLen = %d",ucKeyId,EDataLen,SignatureLen);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	if(g_bLogClearSecret == false)
	{
		sprintf(csLog,"Edata=%s, HexSignature = %s",HexEData, HexSignature);
		g_Log.WriteLog(csLog);
	}

	int i=0;
	int nReturnValue=-1;

	unsigned char *CommandData=new unsigned char[EDataLen+SignatureLen+255];
	memset(CommandData,0,EDataLen+SignatureLen+255);

	CommandData[0] = 0x1b;
	CommandData[1] = 0x47;
	CommandData[2] = 0x56;
	CommandData[3] = (EDataLen+SignatureLen+4)/256;
	CommandData[4] = (EDataLen+SignatureLen+4)%256;
	CommandData[5] = ucKeyId/256;
	CommandData[6] = ucKeyId%256;
	CommandData[7] = EDataLen+SignatureLen;


	for (i = 0; i < SignatureLen; i++)
	{
		CommandData[8+i] = Signature[i];
	}

	for (i = 0; i < EDataLen; i++)
	{
		CommandData[8+SignatureLen+i] = EData[i];
	}

	for(i=0; i < (8+EDataLen+SignatureLen); i++)
		CommandData[8+EDataLen+SignatureLen]^=CommandData[i];

	CommandData[9 + EDataLen+SignatureLen ]=0x0d;
	CommandData[10 + EDataLen+SignatureLen]=0x0a;

	i = SUNSON_SendDataToCom(CommandData,11 +EDataLen+SignatureLen);
	if((11 + EDataLen+SignatureLen)  == i)
	{
		nReturnValue = SUNSON_Read_Com_String(false,ReturnInfo);
		if (nReturnValue > 0)
		{
			//unsigned char temp[1024] = {0};
			//hex_asc(ReturnInfo,temp,nReturnValue);
			sprintf(csLog,"SUNSON_SerialVerifySM2SignatureEX, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			unsigned char ResultInfo[2] = {0};
			hex_asc_char(ReturnInfo[0],ResultInfo);
			sprintf(csLog,"SUNSON_SerialVerifySM2SignatureEX, ReturnInfo = 0x%c%c(失败)",ResultInfo[0],ResultInfo[1]);
			g_Log.WriteLog(csLog);
		}
		delete [] CommandData;
		CommandData=NULL;
		return nReturnValue;
	}
	else
	{
		sprintf(csLog,"SUNSON_SerialVerifySM2SignatureEX, ReturnInfo = 0x%02x(失败)",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		delete [] CommandData;
		CommandData=NULL;
		return 0;
	}
}

////1.40 SM2验签,兼容F35接口，OpenFlag忽略
int SUNSON_SerialVerifySM2Signature(int ucKeyId,unsigned char OpenFlag,int SignatureLen,
		unsigned char *Signature,int EDataLen,unsigned char *EData,unsigned char *ReturnInfo)
{
	char csLog[2048] = {0};
	unsigned char HexEData[1024] = {0};
	hex_asc(EData,HexEData,EDataLen);
	sprintf(csLog,"SUNSON_SerialVerifySM2Signature, ucKeyId = %d,EDataLen = %d,EData = %s",ucKeyId,EDataLen, (char*)HexEData);
	g_Log.WriteLog(csLog);
	//初始化userid
	SUNSON_InitHashID(ucKeyId, EData[0], EData+1, ReturnInfo);
	//SM3计算E值
	unsigned char ucResult[256]={0};
	int nlen = SUNSON_SM3HashOperateEX(0x06, EDataLen-EData[0]-1, EData+1+EData[0], ucResult);
	return SUNSON_VerifySM2SignatureEX(ucKeyId, nlen, ucResult, SignatureLen, Signature, ReturnInfo);
}

//SM2数据运算
int SUNSON_SerialSM2DataCompute(int ucKeyId,unsigned char ucKeyType,int nDatalen,unsigned char *data,unsigned char *DataResult)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---SM2数据运算---");
	char csLog[5120] = {0};
	sprintf(csLog,"SUNSON_SerialSM2DataCompute, ucKeyId = %d,ucKeyType, = %02x,nDatalen = %d",ucKeyId,ucKeyType,nDatalen);
	g_Log.WriteLog(csLog);
	*DataResult = 0x00;

	if(g_bLogClearSecret == false)
	{
		unsigned char HexEData[2048] = {0};
		hex_asc(data,HexEData,nDatalen);
		sprintf(csLog,"data = %s",HexEData);
		g_Log.WriteLog(csLog);
	}

	unsigned char *CommandData=new unsigned char[nDatalen+255];
	memset(CommandData,0,nDatalen+255);

	int i = 0;
	int nReturnValue=-1;
	CommandData[0] = 0x1b;
	CommandData[1] = 0x44;
	CommandData[2] = 0x4c;
	CommandData[3] = (nDatalen+5)/256;
	CommandData[4] = (nDatalen+5)%256;
	CommandData[5] = ucKeyType;
	CommandData[6] = ucKeyId/256;
	CommandData[7] = ucKeyId%256;
	CommandData[8] = nDatalen;

	for(i=0; i<nDatalen; i++)
		CommandData[9+i] = data[i];

	int templen = 9+nDatalen;
	for(i=0;i<templen;i++)
		CommandData[templen]^=CommandData[i];

	CommandData[10+nDatalen] = 0x0d;
	CommandData[11+nDatalen] = 0x0a;

	i=SUNSON_SendDataToCom(CommandData,12+nDatalen);
	if(i==(12+nDatalen))
	{
		nReturnValue=SUNSON_Read_Com_String(false,DataResult);
		if (nReturnValue>0)
		{
			unsigned char temp[5120] = {0};
			hex_asc(DataResult,temp,nReturnValue);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_SerialSM2DataCompute, DataResult = %s",temp);
			else
				sprintf(csLog,"SUNSON_SerialSM2DataCompute, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			unsigned char ResultInfo[2] = {0};
			hex_asc_char(DataResult[0],ResultInfo);
			sprintf(csLog,"SUNSON_SerialSM2DataCompute, ReturnInfo = 0x%c%c(失败)",ResultInfo[0],ResultInfo[1]);
			g_Log.WriteLog(csLog);
		}
		delete [] CommandData;
		CommandData=NULL;
		return nReturnValue;
	}
	else
	{
		sprintf(csLog,"SUNSON_SerialSM2DataCompute, ReturnInfo = 0x%02x(失败)",DataResult[0]);
		g_Log.WriteLog(csLog);
		delete [] CommandData;
		CommandData=NULL;
		return 0;
	}
}

//SM3哈希操作,
int SUNSON_SerialSM3HashOperateEX(unsigned char ucSM3HashType,int nDatalen,unsigned char *data,unsigned char *DataResult)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---SM3哈希操作---");
	unsigned char HexData[1024] = {0};
	hex_asc(data,HexData,nDatalen);
	char csLog[2048] = {0};
	sprintf(csLog,"SUNSON_SerialSM3HashOperateEX,ucKeyType = %02x,nDatalen = %d",ucSM3HashType,nDatalen);
	g_Log.WriteLog(csLog);
	*DataResult = 0x00;
	if(g_bLogClearSecret == false)
	{
		sprintf(csLog,"data = %s",HexData);
		g_Log.WriteLog(csLog);
	}	

	unsigned char *CommandData=new unsigned char[nDatalen+255];
	memset(CommandData,0,nDatalen+255);

	int i=0;
	int nReturnValue=-1;
	CommandData[0] = 0x1b;
	CommandData[1] = 0x44;
	CommandData[2] = 0x46;
	CommandData[3] = (nDatalen+4)/256;
	CommandData[4] = (nDatalen+4)%256;
	CommandData[5] = ucSM3HashType;
	CommandData[6] = nDatalen/256;
	CommandData[7] = nDatalen%256;

	for(i=0; i<nDatalen; i++)
		CommandData[8+i] = data[i];

	int templen = 8+nDatalen;
	for(i=0;i<templen;i++)
		CommandData[templen]^=CommandData[i];

	CommandData[9+nDatalen] = 0x0d;
	CommandData[10+nDatalen] = 0x0a;

	i=SUNSON_SendDataToCom(CommandData,11+nDatalen);
	if(i==(11+nDatalen))
	{
		nReturnValue=SUNSON_Read_Com_String(true,DataResult);
		if (nReturnValue>0)
		{
			unsigned char temp[2048] = {0};
			hex_asc(DataResult,temp,nReturnValue);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_SerialSM3HashOperateEX, DataResult = %s",temp);
			else
				sprintf(csLog,"SUNSON_SerialSM3HashOperateEX, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			unsigned char ResultInfo[2] = {0};
			hex_asc_char(DataResult[0],ResultInfo);
			sprintf(csLog,"SUNSON_SerialSM3HashOperateEX, ReturnInfo = 0x%c%c(失败)",ResultInfo[0],ResultInfo[1]);
			g_Log.WriteLog(csLog);
		}
		delete [] CommandData;
		CommandData=NULL;
		return nReturnValue;
	}
	else
	{
		sprintf(csLog,"SUNSON_SerialSM3HashOperateEX, ReturnInfo = 0x%02x(失败)",DataResult[0]);
		g_Log.WriteLog(csLog);
		delete [] CommandData;
		CommandData=NULL;
		return 0;
	}
}


//使能国密程序下载
int SUNSON_SerialEnableLoadSMFirmware(void)
{
	CCriticalSection autoSc;
	int i = -1;
	int ST = -1;
	unsigned char ReturnInfo[64] = {0};
	unsigned char command[8] = {0x1B,0x47,0x44,0x00,0x01,0x00,0x0d,0x0a};
	command[5] = command[0]^command[1]^command[2]^command[3]^command[4];

	g_Log.WriteLog("****使用国密程序下载****");

	i = SUNSON_SendDataToCom(command,8);
	if(8 == i)
	{
		ST = SUNSON_ReturnST(ReturnInfo);
		if (1 == ST)
		{
			g_Log.WriteLog("使用国密程序下载成功！");
		}
		else
		{
			g_Log.WriteLog("使用国密程序下载失败！");
		}
		return ST;
	}
	else
		return 0;
}


//导入SM4密钥，通过SM2解密
int SUNSON_SerialImportSM4KeyUseSM2key(int nSM2keyID, int nSM4keyID, int nKeyAttr, int nKeyLen, unsigned char* KeyValue, unsigned char* ReturnInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---下载SM4密钥使用SM2解密---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SerialImportSM4KeyUseSM2key,nSM2keyID = %02x,nSM4keyID = %02x,KeyAtt = %02x,keyValueLength = %d",nSM2keyID,nSM4keyID,nKeyAttr,nKeyLen);
	g_Log.WriteLog(csLog);
	unsigned char temptxt[512]={0};
	hex_asc(KeyValue, temptxt, nKeyLen);
	if(g_bLogClearSecret == false)
		g_Log.WriteLog((char*)temptxt);
	*ReturnInfo = 0x00;

	int i=0;
	//int len=0;
	int nReturnValue=-1;
	unsigned char CommandData[1024];
	memset(CommandData,0,1024);
	CommandData[0]=0x1b;
	CommandData[1]=0x5A;
	CommandData[2]=0x41;
	CommandData[3]=0x00;
	CommandData[4]=9+nKeyLen;
	CommandData[5]=nSM4keyID/256;
	CommandData[6]=nSM4keyID%256;
	CommandData[7]=nSM2keyID/256;
	CommandData[8]=nSM2keyID%256;
	CommandData[12]=nKeyAttr;
	
	for(i=0;i<nKeyLen;i++)
	{
		CommandData[13+i]=KeyValue[i];
	}

	for(i=0;i<13+nKeyLen;i++)
		CommandData[13+nKeyLen]^=CommandData[i];
	CommandData[14+nKeyLen]=0x0d;
	CommandData[15+nKeyLen]=0x0a;

	i=SUNSON_SendDataToCom(CommandData,16+nKeyLen);
	if(i==16+nKeyLen)
	{
		nReturnValue=SUNSON_Read_Com_String(false, ReturnInfo);
		if (nReturnValue > 0)
		{
			unsigned char temp[1024] = {0};
			hex_asc(ReturnInfo,temp,nReturnValue);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_SerialImportSM4KeyUseSM2key, Value = %s",temp);
			else 
				sprintf(csLog,"SUNSON_SerialImportSM4KeyUseSM2key,success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			sprintf(csLog,"SUNSON_SerialImportSM4KeyUseSM2key,failure! errorinfo = 0x%02x",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		return nReturnValue;	
	}
	else
	{
		sprintf(csLog,"SUNSON_SerialImportSM4KeyUseSM2key,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}

//设置能否重复下载密钥 00 允许重复下载； 01 不允许重复下载
int SUNSON_SerialEnableLoadSameKey(unsigned char Mode, unsigned char *ReturnInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("****设置密钥重复下载****");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SerialEnableLoadSameKey,ucSMMode = 0x%02X",Mode);
	g_Log.WriteLog(csLog);
	int i = -1;
	int ST = -1;
	unsigned char command[32] = {0};
	command[0] = 0x1b;
	command[1] = 0x4b;
	command[2] = 0x52;
	command[3] = 0x00;
	command[4] = 0x02;
	command[5] = Mode;

	for(i=0;i<6;i++)
		command[6]^=command[i];

	command[7] = 0x0d;
	command[8] = 0x0a;

	i = SUNSON_SendDataToCom(command,9);
	if(9 == i)
	{
		ST = SUNSON_ReturnST(ReturnInfo);
		if (1 == ST)
		{
			g_Log.WriteLog("设置密钥重复下载模式成功！");
		}
		else
			g_Log.WriteLog("设置密钥重复下载模式失败！");
		return ST;
	}
	else
		return 0;
}

//获取指定密钥的KCV
int SUNSON_SerialGetKCV(int keyId, unsigned char ucCheckMode,unsigned char *CheckValue)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("****获取指定密钥的KCV****");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SerialGetKCV,keyId=0x%02X, ucMode = 0x%02X", keyId, ucCheckMode);
	g_Log.WriteLog(csLog);
	int i = -1;
	int ST = -1;
	short mode=0;
	mode = ucCheckMode + (((short)keyId)<<4);
	*CheckValue = 0x00;

	unsigned char ucMode[3] = {0};
	ucMode[0] = (char)(mode>>8);
	ucMode[1] = (char)mode;

	unsigned char command[32] = {0};
	command[0] = 0x1b;
	command[1] = 0x54;
	command[2] = 0x31;
	command[3] = 0x00;
	command[4] = 0x03;
	command[5] = ucMode[0];
	command[6] = ucMode[1];

	for(i=0;i<7;i++)
		command[7]^=command[i];

	command[8] = 0x0d;
	command[9] = 0x0a;

	i = SUNSON_SendDataToCom(command,10);
	if(10 == i)
	{
		ST=SUNSON_Read_Com_String(false,CheckValue);
		if (ST>0)
		{
			unsigned char temp[1024] = {0};
			hex_asc(CheckValue,temp,ST);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_SerialGetKCV, CheckValue = %s",temp);
			else
				sprintf(csLog,"SUNSON_SerialGetKCV, success");
	
			g_Log.WriteLog(csLog);
		}
		else
		{
			unsigned char ResultInfo[2] = {0};
			hex_asc_char(CheckValue[0],ResultInfo);
			sprintf(csLog,"SUNSON_SerialGetKCV, ReturnInfo = 0x%c%c(失败)",ResultInfo[0],ResultInfo[1]);
			g_Log.WriteLog(csLog);
		}
		return ST;
	}
	else
		return 0;
}

//获取密钥属性值
int SUNSON_SerialGetKeyAttInfo(int UserKeyId,unsigned char *KeyAttInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---获取密钥属性---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SerialGetKeyAttInfo,UserKeyId = %02x",UserKeyId);
	g_Log.WriteLog(csLog);
	*KeyAttInfo = 0x00;

	int i=0;
	int nReturnValue=-1;
	unsigned char CommandData[10]={0x1b,0x45,0x53,0x00,0x03,0x00,0x00,0x00,0x0d,0x0a};
	CommandData[5]=UserKeyId/256;
	CommandData[6]=UserKeyId%256;
	for(i=0;i<7;i++)
		CommandData[7]^=CommandData[i];
	i=SUNSON_SendDataToCom(CommandData,10);
	if(i==10)
	{
		nReturnValue=SUNSON_Read_Com_String(false,KeyAttInfo);
		if (nReturnValue>0)
		{
			unsigned char temp[1024] = {0};
			hex_asc(KeyAttInfo,temp,nReturnValue);
			sprintf(csLog,"SUNSON_SerialGetKeyAttInfo, DataResult = %s",temp);
			g_Log.WriteLog(csLog);
		}
		else
		{
			unsigned char ResultInfo[2] = {0};
			hex_asc_char(KeyAttInfo[0],ResultInfo);
			sprintf(csLog,"SUNSON_SerialGetKeyAttInfo, ReturnInfo = 0x%c%c(失败)",ResultInfo[0],ResultInfo[1]);
			g_Log.WriteLog(csLog);
		}
		return nReturnValue;
	}
	else
	{
		sprintf(csLog,"SUNSON_SerialGetKeyAttInfo, ReturnInfo = 0x%02x(失败)",KeyAttInfo[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}

//设置波特率 mode 0x30 2400:
//  0x31 4800:
//  0x32 9600
//  0x33 19200
//  0x34 38400
//  0x35 57600
//  0x36 115200
int SUNSON_SerialSetBaudRate(unsigned char ucBaudRateMode,unsigned char *ReturnInfo)
{	
	CCriticalSection autoSc;
	g_Log.WriteLog("---设置波特率---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SerialSetBaudRate,ucBaudRateMode = %d",ucBaudRateMode);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	int nReturnValue=-1;
	unsigned char CommandData[9]={0x1b,0x53,0x42,0x00,0x02,0x00,0x00,0x0d,0x0a};	
	CommandData[5]=ucBaudRateMode;
	for(int i=0;i<6;i++)
		CommandData[6]^=CommandData[i];
	
	int i=SUNSON_SendDataToCom(CommandData,9);
	if(i==9)
	{
		nReturnValue=SUNSON_ReturnST(ReturnInfo);
		if (nReturnValue ==1)
		{
			g_Log.WriteLog("SUNSON_SerialSetBaudRate,success!");
		}
		else
		{
			sprintf(csLog,"SUNSON_SerialSetBaudRate,failure! errorinfo1 = 0x%02x",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		return nReturnValue;		
	}
	else
	{
		sprintf(csLog,"SUNSON_SerialSetBaudRate,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}

//开关usb明文系统键盘
//                      0x01   关闭系统键盘
//                      0x02   开启系统键盘              
int SUNSON_SerialEnableUSBplaintext(unsigned char mode)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---使能系统键盘功能---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SerialEnableUSBplaintext,mode = %d",mode);
	g_Log.WriteLog(csLog);

	unsigned char ReturnInfo[256] = {0};

	int i=0;
	int nReturnValue=-1;
	unsigned char CommandData[10]={0x1b,0x54,0x4d,0x00,0x02,mode,0x00,0x0d,0x0a};
	for(i=0;i<6;i++)
		CommandData[6]^=CommandData[i];

	i=SUNSON_SendDataToCom(CommandData,9);
	if(i==9)
	{
		nReturnValue=SUNSON_ReturnST(ReturnInfo);
		if (nReturnValue==1)
		{
			sprintf(csLog,"SUNSON_SerialEnableUSBplaintext, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			sprintf(csLog,"SUNSON_SerialEnableUSBplaintext, ReturnInfo = 0x%02x(失败)",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
			return 0;
		}
		return nReturnValue;	
	}
	else 
	{
		sprintf(csLog,"SUNSON_SerialEnableUSBplaintext, failed");
		g_Log.WriteLog(csLog);
		return 0;
	}
	return 0;
}


//导出RSA密钥
int SUNSON_SerialExportRSAKey(unsigned char ucKeyId, unsigned char *ucData)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---导出RSA密钥---");
	char csLog[4096] = {0};
	sprintf(csLog,"SUNSON_SerialExportRSAKey, KeyID = %d",ucKeyId);
	g_Log.WriteLog(csLog);

	int i=0;
	int ST=-1;
	unsigned char CommandData[10] = {0x1b,0x45,0x50,0x00,0x02,ucKeyId, 0x00,0x0D,0x0A};
	for (i = 0 ; i < 6 ; i++)
	{
		CommandData[6] ^= CommandData[i];
	}

	i=SUNSON_SendDataToCom(CommandData,9);
	if(i==9)
	{
		ST=SUNSON_Read_Com_String(true, ucData);
		if (ST>0)
		{
			unsigned char temp[4096] = {0};
			hex_asc(ucData,temp,ST);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_SerialExportRSAKey, ucData = %s",temp);
			else
				sprintf(csLog,"SUNSON_SerialExportRSAKey, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			sprintf(csLog,"SUNSON_SerialExportRSAKey, ReturnInfo = 0x%02x(失败)",ucData[0]);
			g_Log.WriteLog(csLog);
			return 0;
		}
		return ST;
	}
	else
	{
		sprintf(csLog,"SUNSON_SerialExportRSAKey,failure! errorinfo = 0x%02x",ucData[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}
//下载RSA密钥（部分键盘支持）
int SUNSON_SerialLoadRSAKey(unsigned char ucKeyId,unsigned char nSignatureId, int nKeylen, unsigned char *KeyValue, int nSignatureLen, unsigned char* SignatureData, unsigned char * ReturnInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---下载RSA密钥---");
	char csLog[2048] = {0};
	sprintf(csLog,"SUNSON_SerialLoadRSAKey,KeyId = %02x,signatureId = %02x,keyLength = %d, signatureLen=%d",ucKeyId,nSignatureId,nKeylen,nSignatureLen);
	g_Log.WriteLog(csLog);

	unsigned char temp[1024] = {0};
	unsigned char temp2[1024] = {0};
	hex_asc(KeyValue,temp,nKeylen);
	hex_asc(SignatureData,temp2,nSignatureLen);

	if(g_bLogClearSecret == false)
	{
		sprintf(csLog,"keyvalue=%s, signdata=%s",temp,temp2);
		g_Log.WriteLog(csLog);
	}

	int i=0, nReturnValue = 0;
	unsigned char CommandData[4096] = {0};
	CommandData[0] = 0x1B;
	CommandData[1] = 0x4C;
	CommandData[2] = 0x52;
	CommandData[3] = (nKeylen + nSignatureLen + 7)/256;
	CommandData[4] = (nKeylen + nSignatureLen + 7)%256;
	CommandData[5] = ucKeyId;
	CommandData[6] = nSignatureId;
	CommandData[7] = (nKeylen >> 8) & 0xFF;
	CommandData[8] = nKeylen & 0xFF;
	memcpy(&CommandData[9], KeyValue, nKeylen);
	CommandData[nKeylen+9] = (nSignatureLen >>8) & 0xFF;
	CommandData[nKeylen+10] = nSignatureLen & 0xFF;
	memcpy(&CommandData[nKeylen+11], SignatureData, nSignatureLen);
	for (i = 0; i < nKeylen+nSignatureLen+11; i++)
	{
		CommandData[nKeylen+nSignatureLen+11] ^=  CommandData[i];
	}
	CommandData[nKeylen+nSignatureLen+12] = 0x0D;
	CommandData[nKeylen+nSignatureLen+13] = 0x0A;

	i=SUNSON_SendDataToCom(CommandData,14+nKeylen+nSignatureLen);
	if(i==(14+nKeylen+nSignatureLen))
	{
		nReturnValue=SUNSON_ReturnST(ReturnInfo,true);
		if (nReturnValue ==1)
		{
			g_Log.WriteLog("SUNSON_SerialLoadRSAKey,success!");
		}
		else
		{
			sprintf(csLog,"SUNSON_SerialLoadRSAKey,failure! errorinfo1 = 0x%02x",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
			return 0;
		}
		return nReturnValue;	
	}
	else
	{
		sprintf(csLog,"SUNSON_SerialLoadRSAKey,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}

//RSA签名
int SUNSON_SerialGetRSASignature(unsigned char ucKeyId, unsigned char Padding,unsigned char HashId,int DataLen,
											   unsigned char *ucData,unsigned char *DataResult)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---RSA签名---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SerialGetRSASignature, KeyID = %d,Padding = %X, HashId = %X",ucKeyId, Padding, HashId);
	g_Log.WriteLog(csLog);
	*DataResult = 0x00;

	int i = 0;
	unsigned char *CommandData=new unsigned char[DataLen+255];
	memset(CommandData,0,DataLen+255);
	CommandData[0] = 0x1B;
	CommandData[1] = 0x52;
	CommandData[2] = 0x47;
	CommandData[3] = ((DataLen + 6)/256) & 0xFF;
	CommandData[4] = ((DataLen + 6)%256) & 0xFF;
	CommandData[5] = ucKeyId;
	CommandData[6] = Padding;
	CommandData[7] = HashId;
	CommandData[8] = (DataLen/256) & 0xFF;
	CommandData[9] = (DataLen%256) & 0xFF;
	memcpy(&CommandData[10], ucData, DataLen);

	for (i = 0; i < DataLen+10; i++)
	{
		CommandData[DataLen+10] ^= CommandData[i];
	}
	CommandData[DataLen+11] = 0x0D;
	CommandData[DataLen+12] = 0x0A;
	i=SUNSON_SendDataToCom(CommandData,DataLen+13);
	if(i==(DataLen+13))
	{
		int ReturnLen = SUNSON_Read_Com_String(true, DataResult);
		if (ReturnLen>0)
		{
			unsigned char temp[1024] = {0};
			hex_asc(DataResult,temp,ReturnLen);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_SerialGetRSASignature, ucData = %s",temp);
			else
				sprintf(csLog,"SUNSON_SerialGetRSASignature, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			sprintf(csLog,"SUNSON_SerialGetRSASignature, ReturnInfo = 0x%02x(失败)",DataResult[0]);
			g_Log.WriteLog(csLog);
		}
		delete []CommandData;
		CommandData = NULL;

		return ReturnLen;
	}
	else
	{
		sprintf(csLog,"SUNSON_SerialGetRSASignature,failure! errorinfo = 0x%02x",DataResult[0]);
		g_Log.WriteLog(csLog);
		delete []CommandData;
		CommandData = NULL;
		return 0;
	}
}

//RSA验签
int SUNSON_SerialVerifyRSASignature(unsigned char ucKeyId, unsigned char Padding,unsigned char HashId,int SignLen,
												  unsigned char *SignData,int DataLen,unsigned char *ucData,unsigned char *ReturnInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---RSA验签---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SerialVerifyRSASignature, KeyID = %d,Padding = %X, HashId = %X",ucKeyId, Padding, HashId);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	unsigned char *CommandData=new unsigned char[DataLen+SignLen+255];
	memset(CommandData,0,DataLen+SignLen+255);
	CommandData[0] = 0x1B;
	CommandData[1] = 0x52;
	CommandData[2] = 0x56;
	CommandData[3] = ((DataLen + SignLen + 8)/256) & 0xFF;
	CommandData[4] = ((DataLen + SignLen + 8)%256) & 0xFF;
	CommandData[5] = ucKeyId;
	CommandData[6] = Padding;
	CommandData[7] = HashId;
	CommandData[8] = (SignLen/256) & 0xFF;
	CommandData[9] = (SignLen%256) & 0xFF;
	memcpy(&CommandData[10], SignData, SignLen);
	CommandData[SignLen+10] = (DataLen/256) & 0xFF;
	CommandData[SignLen+11] = (DataLen%256) & 0xFF;
	memcpy(&CommandData[SignLen+12], ucData, DataLen);

	for (int i = 0; i < DataLen+SignLen+12; i++)
	{
		CommandData[DataLen+SignLen+12] ^= CommandData[i];
	}
	CommandData[DataLen+SignLen+13] = 0x0D;
	CommandData[DataLen+SignLen+14] = 0x0A;
	int iRet=SUNSON_SendDataToCom(CommandData,DataLen+SignLen+15);
	if(iRet==(DataLen+SignLen+15))
	{
		int ReturnLen = SUNSON_ReturnST(ReturnInfo);
		if (ReturnLen ==1)
		{
			g_Log.WriteLog("SUNSON_SerialVerifyRSASignature,success!");
		}
		else
		{
			sprintf(csLog,"SUNSON_SerialVerifyRSASignature,failure! errorinfo1 = 0x%02x",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		delete []CommandData;
		CommandData = NULL;
		return ReturnLen;
	}
	else
	{
		sprintf(csLog,"SUNSON_SerialVerifyRSASignature,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		delete []CommandData;
		CommandData = NULL;
		return 0;
	}
}

//RSA导出签名DER（部分键盘支持）
int SUNSON_SerialExportRSASignDer(unsigned char ucKeyId, unsigned char SignkeyId, unsigned long SignAlg, unsigned char *ucData)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---RSA导出签名DER---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SerialExportRSASignDer, KeyId = %d, SignkeyId = %d",	ucKeyId, SignkeyId);
	g_Log.WriteLog(csLog);
	*ucData = 0x00;
	int i = 0;

	unsigned char ucCommand[14] = {0x1B,0x41,0x53,0x00,0x07,ucKeyId,SignkeyId,0x00,0x00,0x00,0x00,0x00,0x0D,0x0A};
	ucCommand[7] = (SignAlg >> 24) & 0xFF;
	ucCommand[8] = (SignAlg >> 16) & 0xFF;
	ucCommand[9] = (SignAlg >> 8) & 0xFF;
	ucCommand[10] = SignAlg & 0xFF;
	for (i = 0; i < 11; i++)
	{
		ucCommand[11] ^= ucCommand[i];
	}
	i=SUNSON_SendDataToCom(ucCommand,14);
	if(i==14)
	{
		int ReturnLen = SUNSON_Read_Com_String(true, ucData);
		if (ReturnLen>0)
		{
			unsigned char temp[1024] = {0};
			hex_asc(ucData,temp,ReturnLen);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_SerialExportRSASignDer, ucData = %s",temp);
			else
				sprintf(csLog,"SUNSON_SerialExportRSASignDer, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			sprintf(csLog,"SUNSON_SerialExportRSASignDer, ReturnInfo = 0x%02x(失败)",ucData[0]);
			g_Log.WriteLog(csLog);
		}
		return ReturnLen;
	}
	else
	{
		sprintf(csLog,"SUNSON_SerialExportRSASignDer,failure! errorinfo = 0x%02x",ucData[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}


//导入无签名的RSAKEY KeyType = 0x01 导DER私钥
//                   KeyType = 0x02 导DER公钥
int SUNSON_SerialImportNoSignRSAKey(unsigned char ucKeyId, unsigned char KeyType, int DataLen,unsigned char *ucData,unsigned char *ReturnInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---导入无签名的RSAKEY---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SerialImportNoSignRSAKey, KeyId = %d, KeyType=%d", ucKeyId, KeyType);
	g_Log.WriteLog(csLog);

	unsigned char *CommandData=new unsigned char[DataLen+255];
	memset(CommandData,0,DataLen+255);
	CommandData[0] = 0x1B;
	CommandData[1] = 0x4C;
	CommandData[2] = 0x4E;
	CommandData[3] = (DataLen+5)/256 & 0xFF;
	CommandData[4] = (DataLen+5)%256 & 0xFF;
	CommandData[5] = ucKeyId;
	CommandData[6] = KeyType;
	CommandData[7] = (DataLen/256) & 0xFF;
	CommandData[8] = (DataLen%256) & 0xFF;
	memcpy(&CommandData[9], ucData, DataLen);
	for (int i = 0; i < (DataLen+9); i++)
	{
		CommandData[DataLen+9] ^= CommandData[i];
	}
	CommandData[DataLen+10] = 0x0D;
	CommandData[DataLen+11] = 0x0A;

	//unsigned char ReturnTxt[1024] = {0};
	//int nRetLen = -1;

	int iRet=SUNSON_SendDataToCom(CommandData,DataLen+12);
	if(iRet==DataLen+12)
	{
		int ReturnLen = SUNSON_ReturnST(ReturnInfo);
		if (ReturnLen ==1)
		{
			g_Log.WriteLog("SUNSON_SerialImportNoSignRSAKey,success!");
		}
		else
		{
			sprintf(csLog,"SUNSON_SerialImportNoSignRSAKey,failure! errorinfo1 = 0x%02x",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		delete []CommandData;
		CommandData = NULL;

		return ReturnLen;
	}
	else
	{
		sprintf(csLog,"SUNSON_SerialImportNoSignRSAKey,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);

		delete []CommandData;
		CommandData = NULL;
		return 0;
	}
}

//生成RSA密钥 nKeylen 1024,2048 exp 3, 17, 65537
int SUNSON_SerialGenerateRSAKey(unsigned char ucKeyId, long nKeylen,long Eval, long Dwuse, unsigned char* ReturnInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---生成RSA密钥---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SerialGenerateRSAKey, wKeyID = %d,ModuleLen = %ld,Eval = %ld, Dwuse = %ld",ucKeyId,nKeylen,Eval,Dwuse);
	g_Log.WriteLog(csLog);

	//int ExpLen = 4;
	//unsigned char ucExp[4] = {0};

	int i=0;
	int ST=-1;
	//unsigned char ucReturnInfo[1024] = {0};
	unsigned char CommandData[21] ={0x1b,0x47,0x41,0x00,0x0E,ucKeyId,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0D,0x0A};
	CommandData[8] = (nKeylen/256) & 0xFF;
	CommandData[9] = (nKeylen%256) & 0xFF;
	CommandData[10] = (Eval >> 24) & 0xFF;
	CommandData[11] = (Eval >> 16) & 0xFF;
	CommandData[12] = (Eval >> 8) & 0xFF;
	CommandData[13] = Eval & 0xFF;
	CommandData[14] = (Dwuse >> 24) & 0xFF;
	CommandData[15] = (Dwuse >> 16) & 0xFF;
	CommandData[16] = (Dwuse >> 8) & 0xFF;
	CommandData[17] = Dwuse & 0xFF;

	for (i = 0 ; i < 18 ; i++)
	{
		CommandData[18] ^= CommandData[i];
	}

	i=SUNSON_SendDataToCom(CommandData,21);
	if(i==21)
	{
		ST=SUNSON_Read_Com_String(true, ReturnInfo, true);
		if (ST ==2)
		{
			g_Log.WriteLog("SUNSON_SerialGenerateRSAKey,success!");
		}
		else
		{
			sprintf(csLog,"SUNSON_SerialGenerateRSAKey,failure! errorinfo1 = 0x%02x",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
			return 0;
		}
		return ST;	
	}
	else
	{
		sprintf(csLog,"SUNSON_SerialGenerateRSAKey,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}

//导出RSA DerKey mode:0x01 DER格式, 0x02:256字节N值
int SUNSON_SerialExportRSADerKey(unsigned char ucKeyId, unsigned char mode, int *nkeyderLen, unsigned char *ucKeyDer, int *nSignLen, unsigned char *ucSignData, unsigned char* ReturnInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---RSA导出DerKey---");
	char csLog[4096] = {0};
	sprintf(csLog,"SUNSON_SerialExportRSADerKey, KeyID = %d, mode=%d",ucKeyId, mode);
	g_Log.WriteLog(csLog);
	unsigned char ucData[4096]={0};
	int i = 0;

	int len = 0;
	if(mode == 0) //0的时候不发mode
	{
		unsigned char ucCommand[12] = {0x1B,0x45,0x52,0x00,0x02,ucKeyId,0x00,0x0D,0x0A};
		for (i = 0; i < 6; i++)
		{
			ucCommand[6] ^= ucCommand[i];
		}
		i=SUNSON_SendDataToCom(ucCommand,9);
		len = 9;
	}
	else
	{
		unsigned char ucCommand[12] = {0x1B,0x45,0x52,0x00,0x03,ucKeyId,mode,0x00,0x0D,0x0A};
		for (i = 0; i < 7; i++)
		{
			ucCommand[7] ^= ucCommand[i];
		}
		i=SUNSON_SendDataToCom(ucCommand,10);
		len = 10;
	}

	if(i==len)
	{
		int ReturnLen = SUNSON_Read_Com_String(true, ucData);
		if (ReturnLen>0)
		{
			unsigned char temp[4096] = {0};
			hex_asc(ucData,temp,ReturnLen);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_SerialExportRSADerKey, ucData = %s",temp);
			else
				sprintf(csLog,"SUNSON_SerialExportRSADerKey, success");
			*nkeyderLen = (ucData[0]<<8)|ucData[1];
			memcpy(ucKeyDer, ucData+2, *nkeyderLen);
			int nlen = 2+(*nkeyderLen);
			*nSignLen = (ucData[nlen]<<8)|ucData[nlen+1];
			memcpy(ucSignData, ucData+nlen+2, *nSignLen);

			g_Log.WriteLog(csLog);
		}
		else
		{
			ReturnInfo[0]=ucData[0];
			sprintf(csLog,"SUNSON_SerialExportRSADerKey, ReturnInfo = 0x%02x(失败)",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		return ReturnLen;
	}
	else
	{
		ReturnInfo[0]=ucData[0];
		sprintf(csLog,"SUNSON_SerialExportRSADerKey,failure! errorinfo = 0x%02x",ucData[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}

//导入RSA DerKey
int SUNSON_SerialImportRSADerKey(unsigned char ucKeyId, unsigned char SignkeyId, int DerKeyLen, unsigned char *DerKey, long Dwuse, 
											   long SignAlg, long CheckMode, int SignLen, unsigned char *SignDat, unsigned char *ucResult)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---RSA导入DerKey---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SerialImportRSADerKey, KeyID = %d,SignkeyId = %X, Dwuse = %ld, SignAlg = %lx, CheckMode = %ld",ucKeyId, SignkeyId, Dwuse, SignAlg, CheckMode);
	g_Log.WriteLog(csLog);
	*ucResult = 0x00;

	unsigned char *CommandData=new unsigned char[DerKeyLen+SignLen+255];
	memset(CommandData,0,DerKeyLen+SignLen+255);
	CommandData[0] = 0x1B;
	CommandData[1] = 0x49;
	CommandData[2] = 0x52;
	CommandData[3] = ((DerKeyLen + SignLen + 19)/256) & 0xFF;
	CommandData[4] = ((DerKeyLen + SignLen + 19)%256) & 0xFF;
	CommandData[5] = ucKeyId;
	CommandData[6] = SignkeyId;
	CommandData[7] = (DerKeyLen/256) & 0xFF;
	CommandData[8] = (DerKeyLen%256) & 0xFF;
	memcpy(&CommandData[9], DerKey, DerKeyLen);
	CommandData[DerKeyLen+9] = (Dwuse >> 24) & 0xFF;
	CommandData[DerKeyLen+10] = (Dwuse >> 16) & 0xFF;
	CommandData[DerKeyLen+11] = (Dwuse >> 8) & 0xFF;
	CommandData[DerKeyLen+12] = Dwuse & 0xFF;
	CommandData[DerKeyLen+13] = (SignAlg >> 24) & 0xFF;
	CommandData[DerKeyLen+14] = (SignAlg >> 16) & 0xFF;
	CommandData[DerKeyLen+15] = (SignAlg >> 8) & 0xFF;
	CommandData[DerKeyLen+16] = SignAlg & 0xFF;
	CommandData[DerKeyLen+17] = (CheckMode >> 24) & 0xFF;
	CommandData[DerKeyLen+18] = (CheckMode >> 16) & 0xFF;
	CommandData[DerKeyLen+19] = (CheckMode >> 8) & 0xFF;
	CommandData[DerKeyLen+20] = CheckMode & 0xFF;
	CommandData[DerKeyLen+21] = (SignLen/256) & 0xFF;
	CommandData[DerKeyLen+22] = (SignLen%256) & 0xFF;
	memcpy(&CommandData[DerKeyLen+23], SignDat, SignLen);
	for (int i = 0; i < DerKeyLen+SignLen+23; i++)
	{
		CommandData[DerKeyLen+SignLen+23] ^= CommandData[i];
	}
	CommandData[DerKeyLen+SignLen+24] = 0x0D;
	CommandData[DerKeyLen+SignLen+25] = 0x0A;
	int iRet=SUNSON_SendDataToCom(CommandData,DerKeyLen+SignLen+26);
	if(iRet==(DerKeyLen+SignLen+26))
	{
		int ReturnLen = SUNSON_Read_Com_String(true, ucResult);
		if (ReturnLen>0)
		{
			unsigned char temp[1024] = {0};
			hex_asc(ucResult,temp,ReturnLen);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_SerialImportRSADerKey, ucData = %s",temp);
			else
				sprintf(csLog,"SUNSON_SerialImportRSADerKey, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			sprintf(csLog,"SUNSON_SerialImportRSADerKey, ReturnInfo = 0x%02x(失败)",ucResult[0]);
			g_Log.WriteLog(csLog);
		}
		delete []CommandData;
		CommandData = NULL;

		return ReturnLen;
	}
	else
	{
		sprintf(csLog,"SUNSON_SerialImportRSADerKey,failure! errorinfo = 0x%02x",ucResult[0]);
		g_Log.WriteLog(csLog);
		delete []CommandData;
		CommandData = NULL;
		return 0;
	}
}

//导入签名值
int SUNSON_SerialImportSignValue(unsigned char ucKeyId, int SignLen, unsigned char * SignData, unsigned char *ReturnInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---RSA导入签名值---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SerialImportSignValue, KeyId = %d",	ucKeyId);
	g_Log.WriteLog(csLog);

	unsigned char *CommandData=new unsigned char[SignLen+255];
	memset(CommandData,0,SignLen+255);
	CommandData[0] = 0x1B;
	CommandData[1] = 0x52;
	CommandData[2] = 0x4C;
	CommandData[3] = (SignLen+4)/256 & 0xFF;
	CommandData[4] = (SignLen+4)%256 & 0xFF;
	CommandData[5] = ucKeyId;
	CommandData[6] = (SignLen/256) & 0xFF;
	CommandData[7] = (SignLen%256) & 0xFF;
	memcpy(&CommandData[8], SignData, SignLen);
	for (int i = 0; i < (SignLen+8); i++)
	{
		CommandData[SignLen+8] ^= CommandData[i];
	}
	CommandData[SignLen+9] = 0x0D;
	CommandData[SignLen+10] = 0x0A;
	int iRet=SUNSON_SendDataToCom(CommandData,SignLen+11);
	if(iRet==(SignLen+11))
	{
		int ReturnLen = SUNSON_ReturnST(ReturnInfo);
		if (ReturnLen ==1)
		{
			g_Log.WriteLog("SUNSON_SerialImportSignValue,success!");
		}
		else
		{
			sprintf(csLog,"SUNSON_SerialImportSignValue,failure! errorinfo = 0x%02x",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		delete []CommandData;
		CommandData = NULL;

		return ReturnLen;
	}
	else
	{
		sprintf(csLog,"SUNSON_SerialImportSignValue,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);

		delete []CommandData;
		CommandData = NULL;
		return 0;
	}
}

//导入RSA签名的DES密钥
int SUNSON_SerialImportRSADesKey(unsigned char nDESKeyId, unsigned char nRSAKeyId, unsigned char SignKeyId, long EncipherAlg, long SignAlg, long Dwuse,
											   int LpxValLen, unsigned char *LpxVal, int LpxSignLen, unsigned char *LpxSign, unsigned char *ucResult)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---RSA导入签名DES密钥值---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SerialImportRSADesKey, nDESKeyId = %d,nRSAKeyId = %X, SignKeyId = %d, EncipherAlg = %ld, SignAlg = %lx, Dwuse = %ld",
		nDESKeyId, nRSAKeyId, SignKeyId, EncipherAlg, SignAlg, Dwuse);
	g_Log.WriteLog(csLog);
	*ucResult = 0x00;

	unsigned char *CommandData=new unsigned char[LpxValLen+LpxSignLen+255];
	memset(CommandData,0,LpxValLen+LpxSignLen+255);
	CommandData[0] = 0x1B;
	CommandData[1] = 0x52;
	CommandData[2] = 0x44;
	CommandData[3] = ((LpxValLen+LpxSignLen+20)/256) & 0xFF;
	CommandData[4] = ((LpxValLen+LpxSignLen+20)%256) & 0xFF;
	CommandData[5] = nDESKeyId;
	CommandData[6] = nRSAKeyId;
	CommandData[7] = SignKeyId;
	CommandData[8] = (EncipherAlg >> 24) & 0xFF;
	CommandData[9] = (EncipherAlg >> 16) & 0xFF;
	CommandData[10] = (EncipherAlg >> 8) & 0xFF;
	CommandData[11] = EncipherAlg & 0xFF;
	CommandData[12] = (SignAlg >> 24) & 0xFF;
	CommandData[13] = (SignAlg >> 16) & 0xFF;
	CommandData[14] = (SignAlg >> 8) & 0xFF;
	CommandData[15] = SignAlg & 0xFF;
	CommandData[16] = (Dwuse >> 24) & 0xFF;
	CommandData[17] = (Dwuse >> 16) & 0xFF;
	CommandData[18] = (Dwuse >> 8) & 0xFF;
	CommandData[19] = Dwuse & 0xFF;
	CommandData[20] = (LpxValLen/256) & 0xFF;
	CommandData[21] = (LpxValLen%256) & 0xFF;
	memcpy(&CommandData[22], LpxVal, LpxValLen);
	CommandData[LpxValLen+22] = (LpxSignLen/256) & 0xFF;
	CommandData[LpxValLen+23] = (LpxSignLen%256) & 0xFF;
	memcpy(&CommandData[LpxValLen+24], LpxSign, LpxSignLen);

	for (int i = 0; i < (LpxValLen+LpxSignLen+24); i++)
	{
		CommandData[LpxValLen+LpxSignLen+24] ^= CommandData[i];
	}
	CommandData[LpxValLen+LpxSignLen+25] = 0x0D;
	CommandData[LpxValLen+LpxSignLen+26] = 0x0A;
	int iRet=SUNSON_SendDataToCom(CommandData,LpxValLen+LpxSignLen+27);
	if(iRet==(LpxValLen+LpxSignLen+27))
	{
		int ReturnLen = SUNSON_Read_Com_String(true, ucResult);
		if (ReturnLen>0)
		{
			unsigned char temp[1024] = {0};
			hex_asc(ucResult,temp,ReturnLen);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_SerialImportRSADesKey, ucData = %s",temp);
			else
				sprintf(csLog,"SUNSON_SerialImportRSADesKey, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			sprintf(csLog,"SUNSON_SerialImportRSADesKey, ReturnInfo = 0x%02x(失败)",ucResult[0]);
			g_Log.WriteLog(csLog);
		}
		delete []CommandData;
		CommandData = NULL;

		return ReturnLen;
	}
	else
	{
		sprintf(csLog,"SUNSON_SerialImportRSADesKey,failure! errorinfo = 0x%02x",ucResult[0]);
		g_Log.WriteLog(csLog);
		delete []CommandData;
		CommandData = NULL;

		return 0;
	}
}

//导入RSAdes密钥分量 
int SUNSON_SerialImportRSADesKeyEx(unsigned char KeyLenMode, unsigned char KcvLenMode, unsigned char KeyCountMode, unsigned char nDESKeyId, unsigned char nRSAKeyId, unsigned char SignKeyId, 							long EncipherAlg, long SignAlg, long dwUse,
						int LpxValLen, unsigned char *LpxVal, int LpxSignLen, unsigned char *LpxSign, unsigned char *ucResult)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---RSA导入签名DES密钥分量---");
	unsigned char tempKey[1024] = {0};
	hex_asc(LpxVal,tempKey,LpxValLen);
	char csLog[2048] = {0};
	sprintf(csLog,"SUNSON_SerialImportRSADesKeyEx, KeyLenMode=%d,KcvLenMode=%d,KeyCountMode=%d,nDESKeyId = %d,nRSAKeyId = %d, SignKeyId = %d, EncipherAlg = %ld, SignAlg = %ld, Dwuse = 0x%02lx, keylen=%d, signlen=%d, keyvalue=%s",
		KeyLenMode,KcvLenMode,KeyCountMode,nDESKeyId, nRSAKeyId, SignKeyId, EncipherAlg, SignAlg, dwUse,LpxValLen,LpxSignLen,(char*)tempKey);
	g_Log.WriteLog(csLog);
	*ucResult = 0x00;

	unsigned char CommandData[4096]={0};
	memset(CommandData,0,4096);
	CommandData[0] = 0x1B;
	CommandData[1] = 0x41;
	CommandData[2] = 0x32;
	CommandData[3] = ((LpxValLen+LpxSignLen+21)/256) & 0xFF;
	CommandData[4] = ((LpxValLen+LpxSignLen+21)%256) & 0xFF;
	CommandData[5] = (KeyLenMode<<6) | (KcvLenMode<<4) | KeyCountMode;

	sprintf(csLog,"mode=0x%02X",CommandData[5]);
	g_Log.WriteLog(csLog);
	
	CommandData[6] = nDESKeyId;
	CommandData[7] = nRSAKeyId;
	CommandData[8] = SignKeyId;
	CommandData[9] = (EncipherAlg >> 24) & 0xFF;
	CommandData[10] = (EncipherAlg >> 16) & 0xFF;
	CommandData[11] = (EncipherAlg >> 8) & 0xFF;
	CommandData[12] = EncipherAlg & 0xFF;
	CommandData[13] = (SignAlg >> 24) & 0xFF;
	CommandData[14] = (SignAlg >> 16) & 0xFF;
	CommandData[15] = (SignAlg >> 8) & 0xFF;
	CommandData[16] = SignAlg & 0xFF;
	CommandData[17] = (dwUse >> 24) & 0xFF;
	CommandData[18] = (dwUse >> 16) & 0xFF;
	CommandData[19] = (dwUse >> 8) & 0xFF;
	CommandData[20] = dwUse & 0xFF;
	CommandData[21] = (LpxValLen/256) & 0xFF;
	CommandData[22] = (LpxValLen%256) & 0xFF;
	memcpy(&CommandData[23], LpxVal, LpxValLen);
	CommandData[LpxValLen+23] = (LpxSignLen/256) & 0xFF;
	CommandData[LpxValLen+24] = (LpxSignLen%256) & 0xFF;
	memcpy(&CommandData[LpxValLen+25], LpxSign, LpxSignLen);

	for (int i = 0; i < (LpxValLen+LpxSignLen+25); i++)
	{
		CommandData[LpxValLen+LpxSignLen+25] ^= CommandData[i];
	}
	CommandData[LpxValLen+LpxSignLen+26] = 0x0D;
	CommandData[LpxValLen+LpxSignLen+27] = 0x0A;
	int iRet=SUNSON_SendDataToCom(CommandData,LpxValLen+LpxSignLen+28);
	if(iRet==(LpxValLen+LpxSignLen+28))
	{
		int ReturnLen = SUNSON_Read_Com_String(true, ucResult);
		if (ReturnLen>0)
		{
			unsigned char temp[1024] = {0};
			hex_asc(ucResult,temp,ReturnLen);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_SerialImportRSADesKeyEx, ucData = %s",temp);
			else
				sprintf(csLog,"SUNSON_SerialImportRSADesKeyEx, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			sprintf(csLog,"SUNSON_SerialImportRSADesKeyEx, ReturnInfo = 0x%02x(失败)",ucResult[0]);
			g_Log.WriteLog(csLog);
		}

		return ReturnLen;
	}
	else
	{
		sprintf(csLog,"SUNSON_SerialImportRSADesKeyEx,failure! errorinfo = 0x%02x",ucResult[0]);
		g_Log.WriteLog(csLog);

		return 0;
	}
}

//导入EPPID和签名值 signAlg 签名算法
int SUNSON_SerialImportEppidAndSignData(unsigned char SignAlg, int nEppidLen, unsigned char *EPPID, int SignLen, unsigned char *SignData, unsigned char* ReturnInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---导入EPPID和签名值---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SerialImportEppidAndSignData,SignAlg = %02x,nEppidLen = %d, SignLen=%d",SignAlg,nEppidLen,SignLen);
	g_Log.WriteLog(csLog);

	int i=0, nReturnValue = 0;
	unsigned char CommandData[4096] = {0};
	CommandData[0] = 0x1B;
	CommandData[1] = 0x4C;
	CommandData[2] = 0x45;
	CommandData[3] = (nEppidLen + SignLen + 6)/256;
	CommandData[4] = (nEppidLen + SignLen + 6)%256;
	CommandData[5] = SignAlg;
	CommandData[6] = (nEppidLen >> 8) & 0xFF;
	CommandData[7] = nEppidLen & 0xFF;
	memcpy(&CommandData[8], EPPID, nEppidLen);
	CommandData[nEppidLen+8] = (SignLen >>8) & 0xFF;
	CommandData[nEppidLen+9] = SignLen & 0xFF;
	memcpy(&CommandData[nEppidLen+10], SignData, SignLen);
	for (i = 0; i < nEppidLen+SignLen+10; i++)
	{
		CommandData[nEppidLen+SignLen+10] ^=  CommandData[i];
	}
	CommandData[nEppidLen+SignLen+11] = 0x0D;
	CommandData[nEppidLen+SignLen+12] = 0x0A;

	i=SUNSON_SendDataToCom(CommandData,13+nEppidLen+SignLen);
	if(i==(13+nEppidLen+SignLen))
	{
		nReturnValue=SUNSON_ReturnST(ReturnInfo);
		if (nReturnValue ==1)
		{
			g_Log.WriteLog("SUNSON_SerialImportEppidAndSignData,success!");
		}
		else
		{
			sprintf(csLog,"SUNSON_SerialImportEppidAndSignData,failure! errorinfo1 = 0x%02x",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		return nReturnValue;	
	}
	else
	{
		sprintf(csLog,"SUNSON_SerialImportEppidAndSignData,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}

//导出EPPID和签名值
int SUNSON_SerialExportEppidAndSignData(unsigned char *SignAlg, int *nEppidLen, unsigned char *EPPID, int *SignLen, unsigned char *SignData, unsigned char* ReturnInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---导出EPPID和签名值---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SerialExportEppidAndSignData");
	g_Log.WriteLog(csLog);
	unsigned char ucData[2048]={0};
	int i = 0;

	unsigned char ucCommand[14] = {0x1B,0x45,0x45,0x00,0x01,0x00,0x0D,0x0A};
	for (i = 0; i < 5; i++)
	{
		ucCommand[5] ^= ucCommand[i];
	}
	i=SUNSON_SendDataToCom(ucCommand,8);
	if(i==8)
	{
		int ReturnLen = SUNSON_Read_Com_String(true, ucData);
		if (ReturnLen>0)
		{
			unsigned char temp[2046] = {0};
			hex_asc(ucData,temp,ReturnLen);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_SerialExportEppidAndSignData, ucData = %s",temp);
			else
				sprintf(csLog,"SUNSON_SerialExportEppidAndSignData, success");
			//解析数据
			*SignAlg = ucData[0];
			*nEppidLen = (ucData[1]<<8)|ucData[2];
			memcpy(EPPID, ucData+3, *nEppidLen);
			int nlen = 3+(*nEppidLen);
			*SignLen = (ucData[nlen]<<8)|ucData[nlen+1];
			memcpy(SignData, ucData+nlen+2, *SignLen);

			g_Log.WriteLog(csLog);
		}
		else
		{
			ReturnInfo[0] = ucData[0];
			sprintf(csLog,"SUNSON_SerialExportEppidAndSignData, ReturnInfo = 0x%02x(失败)",ucData[0]);
			g_Log.WriteLog(csLog);
		}
		return ReturnLen;
	}
	else
	{
		ReturnInfo[0] = ucData[0];
		sprintf(csLog,"SUNSON_SerialExportEppidAndSignData,failure! errorinfo = 0x%02x",ucData[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}

//RSA公私钥运算 mode 0x00私钥运算 0x01公钥运算
int SUNSON_SerialRSACompute(int ucKeyId, unsigned char ucMode, unsigned char Padding,unsigned char HashId,int DataLen,unsigned char *ucData,unsigned char *DataResult)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---RSA数据运算---");
	char csLog[1024] = {0};
	unsigned char temp[1024] = {0};
	hex_asc(ucData, temp, DataLen);
	sprintf(csLog,"SUNSON_SerialRSACompute, KeyID = %d,ucMode = %d,Padding = %X, HashId = %X, datalen=%d",ucKeyId,ucMode, Padding, HashId,DataLen);
	g_Log.WriteLog(csLog);
	*DataResult = 0x00;
	if(g_bLogClearSecret == false)
	{
		sprintf(csLog,"data=%s",temp);
		g_Log.WriteLog(csLog);
	}

	unsigned char *CommandData=new unsigned char[DataLen+255];
	memset(CommandData,0,DataLen+255);
	CommandData[0] = 0x1B;
	CommandData[1] = 0x44;
	CommandData[2] = 0x53;
	CommandData[3] = ((DataLen + 7)/256) & 0xFF;
	CommandData[4] = ((DataLen + 7)%256) & 0xFF;
	CommandData[5] = ucKeyId;
	CommandData[6] = ucMode;
	CommandData[7] = Padding;
	CommandData[8] = HashId;
	CommandData[9] = (DataLen/256) & 0xFF;
	CommandData[10] = (DataLen%256) & 0xFF;
	memcpy(&CommandData[11], ucData, DataLen);
	for (int i = 0; i < DataLen+11; i++)
	{
		CommandData[DataLen+11] ^= CommandData[i];
	}
	CommandData[DataLen+12] = 0x0D;
	CommandData[DataLen+13] = 0x0A;
	int iRet=SUNSON_SendDataToCom(CommandData,DataLen+14);
	if(iRet==(DataLen+14))
	{
		int nReturnValue=SUNSON_Read_Com_String(true,DataResult);
		if (nReturnValue>0)
		{
			unsigned char temp[1024] = {0};
			hex_asc(DataResult,temp,nReturnValue);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_SerialRSACompute, DataResult = %s",temp);
			else
				sprintf(csLog,"SUNSON_SerialRSACompute, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			sprintf(csLog,"SUNSON_SerialRSACompute, ReturnInfo = 0x%02x(失败)",DataResult[0]);
			g_Log.WriteLog(csLog);
		}
		delete [] CommandData;
		CommandData=NULL;
		return nReturnValue;		
	}
	else
	{
		sprintf(csLog,"SUNSON_SerialRSACompute failed, errorinfo = 0x%02x",DataResult[0]);
		g_Log.WriteLog(csLog);
		delete [] CommandData;
		CommandData=NULL;
		return 0;
	}
}

//导出EPP键盘签名的EPPID
int SUNSON_SerialExportEPPsignEPPid(int SignKeyID, unsigned char SignAlgorithm, int *nEppidLen, unsigned char *EPPID, int *SignLen, unsigned char *SignData, unsigned char* ReturnInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---导出键盘自签名EPPID数据---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SerialExportEPPsignEPPid,SignKeyID=%d,SignAlgorithm=%d",SignKeyID,SignAlgorithm);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	int ItemType = 0x01; //导出EPPID
	if(SignKeyID == 0xFFFF)
		SignKeyID = 0;

	int i=0;
	int nReturnValue=-1;
	unsigned char CommandData[255]={0};
	CommandData[0] = 0x1b;
	CommandData[1] = 0x49;
	CommandData[2] = 0x45;
	CommandData[3] = 0x00;
	CommandData[4] = 0x09;
	CommandData[5]=ItemType/256;
	CommandData[6]=ItemType%256;
	CommandData[7]=0x00;
	CommandData[8]=0x00;
	CommandData[9]=SignKeyID/256;
	CommandData[10]=SignKeyID%256;
	CommandData[11]=SignAlgorithm/256;
	CommandData[12]=SignAlgorithm%256;

	for(i=0;i<13;i++)
	{
		CommandData[13] ^= CommandData[i];
	}
	CommandData[14] = 0x0d;
	CommandData[15] = 0x0a;

	i=SUNSON_SendDataToCom(CommandData,16);
	if(i==16)
	{
		nReturnValue=SUNSON_Read_Com_String(true,ReturnInfo,true);
		if (nReturnValue > 0)
		{
			//解析数据
			*nEppidLen = (ReturnInfo[0]<<8)|ReturnInfo[1];
			memcpy(EPPID, ReturnInfo+2, *nEppidLen);
			int nlen = 2+(*nEppidLen);
			*SignLen = (ReturnInfo[nlen]<<8)|ReturnInfo[nlen+1];
			memcpy(SignData, ReturnInfo+nlen+2, *SignLen);

			g_Log.WriteLog("SUNSON_SerialExportEPPsignEPPid,success!");
		}
		else
		{
			sprintf(csLog,"SUNSON_SerialExportEPPsignEPPid,failure! errorinfo1 = 0x%02x",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		return nReturnValue;
	}
	else 
	{
		sprintf(csLog,"SUNSON_SerialExportEPPsignEPPid,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}

//导出EPP键盘签名的公钥数据
int SUNSON_SerialExportEPPsignPublicKey(int keyID, int SignKeyID, unsigned char SignAlgorithm, int *PublicKeyLen, unsigned char* PublicKey,int *EppPrivatekeySignLen, unsigned char *EppPrivatekeySignData, 			int *SignLen, unsigned char *SignData, unsigned char* ReturnInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---导出键盘自签名公钥数据---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SerialExportEPPsignPublicKey,keyID=%d,SignKeyID=%d,SignAlgorithm=%d",keyID,SignKeyID,SignAlgorithm);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	int ItemType = 0x02; //导出公钥

	int i=0;
	int nReturnValue=-1;
	unsigned char CommandData[255]={0};
	CommandData[0] = 0x1b;
	CommandData[1] = 0x49;
	CommandData[2] = 0x45;
	CommandData[3] = 0x00;
	CommandData[4] = 0x09;
	CommandData[5]=ItemType/256;
	CommandData[6]=ItemType%256;
	CommandData[7]=keyID/256;
	CommandData[8]=keyID%256;
	CommandData[9]=SignKeyID/256;
	CommandData[10]=SignKeyID%256;
	CommandData[11]=SignAlgorithm/256;
	CommandData[12]=SignAlgorithm%256;

	for(i=0;i<13;i++)
	{
		CommandData[13] ^= CommandData[i];
	}
	CommandData[14] = 0x0d;
	CommandData[15] = 0x0a;

	i=SUNSON_SendDataToCom(CommandData,16);
	if(i==16)
	{
		nReturnValue=SUNSON_Read_Com_String(true,ReturnInfo,true);
		if (nReturnValue > 0)
		{
			//解析数据
			*PublicKeyLen = (ReturnInfo[0]<<8)|ReturnInfo[1];
			memcpy(PublicKey, ReturnInfo+2, *PublicKeyLen);

			int nlen = 2+(*PublicKeyLen);
			*EppPrivatekeySignLen = (ReturnInfo[nlen]<<8)|ReturnInfo[nlen+1];
			memcpy(EppPrivatekeySignData, ReturnInfo+nlen+2, *EppPrivatekeySignLen);

			int nlen2 = 2+ nlen + (*EppPrivatekeySignLen);
			*SignLen = (ReturnInfo[nlen2]<<8)|ReturnInfo[nlen2+1];
			memcpy(SignData, ReturnInfo+nlen2+2, *SignLen);
			g_Log.WriteLog("SUNSON_SerialExportEPPsignPublicKey,success!");
		}
		else
		{
			sprintf(csLog,"SUNSON_SerialExportEPPsignPublicKey,failure! errorinfo1 = 0x%02x",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		return nReturnValue;
	}
	else 
	{
		sprintf(csLog,"SUNSON_SerialExportEPPsignPublicKey,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}

//设置RKL hash算法 0:NID_MD5, 1:NID_sha1, 2:NID_sha224, 3:NID_sha256
int SUNSON_SerialSetHashMode(int nMode, unsigned char* ReturnInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---设置HASH MODE---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SerialSetHashMode,nMode= %d",nMode);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	int i=0;
	int nReturnValue=-1;
	unsigned char CommandData[10]={0x1b,0x48,0x4D,0x00,0x02,0x00,0x00,0x0d,0x0a};
	CommandData[5]=nMode;
	CommandData[6]=CommandData[0]^CommandData[1]^CommandData[2]^CommandData[3]^CommandData[4]^CommandData[5];
	i=SUNSON_SendDataToCom(CommandData,9);
	if(i==9)
	{
		nReturnValue=SUNSON_ReturnST(ReturnInfo);
		if (nReturnValue ==1)
		{
			g_Log.WriteLog("SUNSON_SerialSetHashMode,success!");
		}
		else
		{
			sprintf(csLog,"SUNSON_SerialSetHashMode,failure! errorinfo1 = 0x%02x",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		return nReturnValue;
	}
	else 
	{
		sprintf(csLog,"SUNSON_SerialSetHashMode,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}

//获取SM2公钥的SM3 KCV值
int SUNSON_SerialGetSM2keySM3kcv(int nSM2keyid, unsigned char* KCV)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---获取SM2公钥的SM3KCV---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SerialGetSM2keySM3kcv,KeyId = %d",nSM2keyid);
	g_Log.WriteLog(csLog);
	*KCV = 0x00;

	int i=0;
	int nReturnValue=-1;
	unsigned char CommandData[20]={0x1b,0x4B,0x56,0x00,0x03,0x00,nSM2keyid,0x00,0x0d,0x0a};
	for(i=0;i<7;i++)
		CommandData[7]^=CommandData[i];

	i=SUNSON_SendDataToCom(CommandData,10);
	if(i==10)
	{
		nReturnValue=SUNSON_Read_Com_String(false,KCV);
		if (nReturnValue>0)
		{
			unsigned char temp[1024] = {0};
			hex_asc(KCV,temp,nReturnValue);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_SerialGetSM2keySM3kcv success, kcv=%s", temp);
			else
				sprintf(csLog,"SUNSON_SerialGetSM2keySM3kcv success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			sprintf(csLog,"SUNSON_SerialGetSM2keySM3kcv, ReturnInfo =  0x%02x(失败)",KCV[0]);
			g_Log.WriteLog(csLog);
		}
		return nReturnValue;
	}
	else 
	{
		sprintf(csLog,"SUNSON_SerialGetSM2keySM3kcv, ReturnInfo = 0x%02x(失败)",KCV[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}
//导入SM2公钥
int SUNSON_SerialImportSM2publickey(int nSm2keyid, int nSignKeyid, int nKeyDatalen, unsigned char * KeyData, int nSM2keyattr, int nSignAlg, int nSignDatalen, unsigned char* SignData, unsigned char* ReturnInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---导入SM2公钥---");
	char csLog[5000] = {0};
	unsigned char tempkey[2048]={0};
	unsigned char tempsign[2048]={0};
	hex_asc(KeyData, tempkey, nKeyDatalen);
	hex_asc(SignData, tempsign, nSignDatalen);
	sprintf(csLog,"SUNSON_SerialImportSM2publickey, nSm2keyid = %d,SignkeyId = %X, nSM2keyattr = %d, SignAlg = %X, datalen =%d, signlen =%d",nSm2keyid, nSignKeyid, nSM2keyattr, nSignAlg, nKeyDatalen, nSignDatalen);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;
	if(g_bLogClearSecret == false)
	{
		sprintf(csLog,"Keydata=%s,SignData=%s",tempkey, tempsign);
		g_Log.WriteLog(csLog);
	}

	unsigned char *CommandData=new unsigned char[nKeyDatalen+nSignDatalen+255];
	memset(CommandData,0,nKeyDatalen+nSignDatalen+255);
	CommandData[0] = 0x1B;
	CommandData[1] = 0x53;
	CommandData[2] = 0x4D;
	CommandData[3] = ((nKeyDatalen + nSignDatalen + 11)/256) & 0xFF;
	CommandData[4] = ((nKeyDatalen + nSignDatalen + 11)%256) & 0xFF;
	CommandData[5] = nSm2keyid;
	CommandData[6] = nSignKeyid;
	memcpy(&CommandData[7], KeyData, nKeyDatalen);
	CommandData[nKeyDatalen+7] = (nSM2keyattr >> 24) & 0xFF;
	CommandData[nKeyDatalen+8] = (nSM2keyattr >> 16) & 0xFF;
	CommandData[nKeyDatalen+9] = (nSM2keyattr >> 8) & 0xFF;
	CommandData[nKeyDatalen+10] = nSM2keyattr & 0xFF;
	CommandData[nKeyDatalen+11] = (nSignAlg >> 24) & 0xFF;
	CommandData[nKeyDatalen+12] = (nSignAlg >> 16) & 0xFF;
	CommandData[nKeyDatalen+13] = (nSignAlg >> 8) & 0xFF;
	CommandData[nKeyDatalen+14] = nSignAlg & 0xFF;
	memcpy(&CommandData[nKeyDatalen+15], SignData, nSignDatalen);
	for (int i = 0; i < nKeyDatalen+nSignDatalen+15; i++)
	{
		CommandData[nKeyDatalen+nSignDatalen+15] ^= CommandData[i];
	}
	CommandData[nKeyDatalen+nSignDatalen+16] = 0x0D;
	CommandData[nKeyDatalen+nSignDatalen+17] = 0x0A;
	int iRet=SUNSON_SendDataToCom(CommandData,nKeyDatalen+nSignDatalen+18);
	if(iRet==(nKeyDatalen+nSignDatalen+18))
	{
		int ReturnLen = SUNSON_Read_Com_String(true, ReturnInfo);
		if (ReturnLen>0)
		{
			//unsigned char temp[1024] = {0};
			//hex_asc(ReturnInfo,temp,nRetlen);
			sprintf(csLog,"SUNSON_SerialImportSM2publickey, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			sprintf(csLog,"SUNSON_SerialImportSM2publickey, ReturnInfo = 0x%02x(失败)",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		delete []CommandData;
		CommandData = NULL;

		return ReturnLen;
	}
	else
	{
		sprintf(csLog,"SUNSON_SerialImportSM2publickey,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		delete []CommandData;
		CommandData = NULL;
		return 0;
	}
}
//导入带SM2签名的SM2加密的SM4密钥
int SUNSON_SerialImportSM4KeyUseSM2keySign(int nSM4keyid, int nSM2keyid, int nSignKeyid, int DecryptAlg, int SignAlg, long nKeyAttr, int nDatalen, unsigned char*Data, int nSignLen, unsigned char* SignData, unsigned char* ReturnInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---导入带SM2签名的SM2加密的SM4密钥---");
	char csLog[5000] = {0};
	unsigned char tempkey[2048]={0};
	unsigned char tempsign[2048]={0};
	hex_asc(Data, tempkey, nDatalen);
	hex_asc(SignData, tempsign, nSignLen);
	sprintf(csLog,"SUNSON_SerialImportSM4KeyUseSM2keySign, nSM4keyid=%d,nSm2keyid = %d,SignkeyId = %X, DecryptAlg = %X, SignAlg = %X,nKeyAttr=%lx, datalen =%d, signlen =%d",nSM4keyid,nSM2keyid, nSignKeyid,DecryptAlg , SignAlg, nKeyAttr, nDatalen, nSignLen);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;
	if(g_bLogClearSecret == false)
	{
		sprintf(csLog,"Keydata=%s, SignData=%s",tempkey,tempsign);
		g_Log.WriteLog(csLog);
	}

	unsigned char *CommandData=new unsigned char[nDatalen+nSignLen+255];
	memset(CommandData,0,nDatalen+nSignLen+255);
	CommandData[0] = 0x1B;
	CommandData[1] = 0x53;
	CommandData[2] = 0x53;
	CommandData[3] = ((nDatalen + nSignLen + 20)/256) & 0xFF;
	CommandData[4] = ((nDatalen + nSignLen + 20)%256) & 0xFF;
	CommandData[5] = nSM4keyid;
	CommandData[6] = nSM2keyid;
	CommandData[7] = nSignKeyid;
	CommandData[8] = (DecryptAlg >> 24) & 0xFF;
	CommandData[9] = (DecryptAlg >> 16) & 0xFF;
	CommandData[10] = (DecryptAlg >> 8) & 0xFF;
	CommandData[11] = DecryptAlg & 0xFF;
	CommandData[12] = (SignAlg >> 24) & 0xFF;
	CommandData[13] = (SignAlg >> 16) & 0xFF;
	CommandData[14] = (SignAlg >> 8) & 0xFF;
	CommandData[15] = SignAlg & 0xFF;
	CommandData[16] = (nKeyAttr >> 24) & 0xFF;
	CommandData[17] = (nKeyAttr >> 16) & 0xFF;
	CommandData[18] = (nKeyAttr >> 8) & 0xFF;
	CommandData[19] = nKeyAttr & 0xFF;
	CommandData[20] = nDatalen/256;
	CommandData[21] = nDatalen%256;
	memcpy(&CommandData[22], Data, nDatalen);
	CommandData[nDatalen+22] = nSignLen/256;
	CommandData[nDatalen+23] = nSignLen%256;
	memcpy(&CommandData[nDatalen+24], SignData, nSignLen);
	for (int i = 0; i < nDatalen+nSignLen+24; i++)
	{
		CommandData[nDatalen+nSignLen+24] ^= CommandData[i];
	}
	CommandData[nDatalen+nSignLen+25] = 0x0D;
	CommandData[nDatalen+nSignLen+26] = 0x0A;
	int iRet=SUNSON_SendDataToCom(CommandData,nDatalen+nSignLen+27);
	if(iRet==(nDatalen+nSignLen+27))
	{
		int ReturnLen = SUNSON_Read_Com_String(true, ReturnInfo);
		if (ReturnLen>0)
		{
			unsigned char temp[1024] = {0};
			hex_asc(ReturnInfo,temp,ReturnLen);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_SerialImportSM4KeyUseSM2keySign, ucData = %s",temp);
			else
				sprintf(csLog,"SUNSON_SerialImportSM4KeyUseSM2keySign, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			sprintf(csLog,"SUNSON_SerialImportSM4KeyUseSM2keySign, ReturnInfo = 0x%02x(失败)",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		delete []CommandData;
		CommandData = NULL;

		return ReturnLen;
	}
	else
	{
		sprintf(csLog,"SUNSON_SerialImportSM4KeyUseSM2keySign,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		delete []CommandData;
		CommandData = NULL;
		return 0;
	}
}
//导出SM2公钥签名
int SUNSON_SerialExportSM2publickeySignData(int nSM2keyid, unsigned char* SignData)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---导出SM2公钥签名---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SerialExportSM2publickeySignData,KeyId = %d",nSM2keyid);
	g_Log.WriteLog(csLog);
	*SignData = 0x00;

	int i=0;
	int nReturnValue=-1;
	unsigned char CommandData[20]={0x1b,0x45,0x47,0x00,0x03,0x00,nSM2keyid,0x00,0x0d,0x0a};
	for(i=0;i<7;i++)
		CommandData[7]^=CommandData[i];

	i=SUNSON_SendDataToCom(CommandData,10);
	if(i==10)
	{
		nReturnValue=SUNSON_Read_Com_String(true,SignData);
		if (nReturnValue>0)
		{
			unsigned char temp[1024] = {0};
			hex_asc(SignData,temp,nReturnValue);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_SerialExportSM2publickeySignData success, SignData=%s", temp);
			else
				sprintf(csLog,"SUNSON_SerialExportSM2publickeySignData success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			sprintf(csLog,"SUNSON_SerialExportSM2publickeySignData, ReturnInfo =  0x%02x(失败)",SignData[0]);
			g_Log.WriteLog(csLog);
		}
		return nReturnValue;
	}
	else 
	{
		sprintf(csLog,"SUNSON_SerialExportSM2publickeySignData, ReturnInfo = 0x%02x(失败)",SignData[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}
//导入SM2公钥签名
int SUNSON_SerialImportSM2publickeySignData(int nSM2keyid, int nSignlen, unsigned char* SignData, unsigned char* ReturnInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---导入SM2公钥签名---");
	char csLog[5000] = {0};
	unsigned char tempsign[2048]={0};
	hex_asc(SignData, tempsign, nSignlen);
	sprintf(csLog,"SUNSON_SerialImportSM2publickeySignData, nSm2keyid = %d,signlen =%d",nSM2keyid, nSignlen);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;
	if(g_bLogClearSecret == false)
	{
		sprintf(csLog,"SignData=%s", tempsign);
		g_Log.WriteLog(csLog);
	}

	unsigned char *CommandData=new unsigned char[nSignlen+255];
	memset(CommandData,0,nSignlen+255);
	CommandData[0] = 0x1B;
	CommandData[1] = 0x49;
	CommandData[2] = 0x47;
	CommandData[3] = ((nSignlen + 3)/256) & 0xFF;
	CommandData[4] = ((nSignlen + 3)%256) & 0xFF;
	CommandData[5] = 0x00;
	CommandData[6] = nSM2keyid;
	memcpy(&CommandData[7], SignData, nSignlen);
	for (int i = 0; i < nSignlen+7; i++)
	{
		CommandData[nSignlen+7] ^= CommandData[i];
	}
	CommandData[nSignlen+8] = 0x0D;
	CommandData[nSignlen+9] = 0x0A;
	int iRet=SUNSON_SendDataToCom(CommandData,nSignlen+10);
	if(iRet==(nSignlen+10))
	{
		int ReturnLen = SUNSON_Read_Com_String(true, ReturnInfo);
		if (ReturnLen>0)
		{
			sprintf(csLog,"SUNSON_SerialImportSM2publickeySignData, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			sprintf(csLog,"SUNSON_SerialImportSM2publickeySignData, ReturnInfo = 0x%02x(失败)",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		delete []CommandData;
		CommandData = NULL;

		return ReturnLen;
	}
	else
	{
		sprintf(csLog,"SUNSON_SerialImportSM2publickeySignData,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		delete []CommandData;
		CommandData = NULL;
		return 0;
	}
}

//设置签名者ID
int SUNSON_SerialSetSignUserID(int nUserIDLen, unsigned char *UserID, unsigned char* ReturnInfo)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---设置签名者ID---");
	char csLog[1024] = {0};
	unsigned char uctemp[1024]={0};
	hex_asc(UserID, uctemp, nUserIDLen);
	sprintf(csLog,"SUNSON_SerialSetSignUserID, nUserIDLen=%d,UserID = %s",nUserIDLen, uctemp);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	int i=0;
	int nReturnValue=-1;
	unsigned char *CommandData=new unsigned char[nUserIDLen+255];
	memset(CommandData,0,nUserIDLen+255);
	CommandData[0] = 0x1b;
	CommandData[1] = 0x53;
	CommandData[2] = 0x43;
	CommandData[3] = (nUserIDLen+1)/256;
	CommandData[4] = (nUserIDLen+1)%256;
	for (i = 0; i < nUserIDLen; i++)
	{
		CommandData[5+i] = UserID[i];
	}

	for(i=0; i < (5+nUserIDLen); i++)

		CommandData[5+nUserIDLen]^=CommandData[i];

	CommandData[6 + nUserIDLen ]=0x0d;
	CommandData[7 + nUserIDLen]=0x0a;


	i = SUNSON_SendDataToCom(CommandData,8 +nUserIDLen);

	if((8 + nUserIDLen)  == i)
	{
		nReturnValue = SUNSON_Read_Com_String(false,ReturnInfo);
		if (nReturnValue > 0)

		{
			sprintf(csLog,"SUNSON_SerialSetSignUserID, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			sprintf(csLog,"SUNSON_SerialSetSignUserID, ReturnInfo = 0x%02x(失败)",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}

		delete [] CommandData;
		CommandData=NULL;
		return nReturnValue;		
	}
	else

	{
		sprintf(csLog,"SUNSON_SetSignUserID failed, errorcode = 0x%02x(失败)",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		delete [] CommandData;
		CommandData=NULL;

		return 0;
	}
}


//民生银行版本接口 设置设备信息
//nType  0x30:厂商信息  最大10个字符
//       0x31:EPP信息   最大20个字符
//       0x32:键盘序列号  最大30个字符
//       0x33:驱动库名称  最大30个字符
int SUNSON_SerialSetDeviceInfo(int nType, unsigned char* InfoData)
{
	CCriticalSection autoSc;

	g_Log.WriteLog("---设置设备信息---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SetDeviceInfo, nType=%d, Info=%s", nType, InfoData);
	g_Log.WriteLog(csLog);
	unsigned char ucData[256]={0};

	int i = 0;

	int nMaxLen=0;
	int len = strlen((char*)InfoData);
	switch(nType)

	{
	case 0x30:
		nMaxLen = 10;
		break;
	case 0x31:

		nMaxLen = 20;
		break;
	case 0x32:
		nMaxLen = 30;
		break;
	case 0x33:
		nMaxLen = 30;
		break;
	default:

		g_Log.WriteLog("无效参数");
		return 0;
	}

	if(len > nMaxLen)

	{
		g_Log.WriteLog("数据参数非法");
		return 0;
	}

	unsigned char ucCommand[128] = {0x1B,0x57,0x53,0x00,0x00,nType,0x00,0x00,0x00};
	ucCommand[3] = (2+len)/256;
	ucCommand[4] = (2+len)%256;


	memcpy(ucCommand+6,InfoData, len);

	for (i = 0; i < (6+len); i++)
	{
		ucCommand[6+len] ^= ucCommand[i];

	}
	ucCommand[7+len] = 0x0d;
	ucCommand[8+len] = 0x0a;
	i=SUNSON_SendDataToCom(ucCommand,9+len);
	if(i==9+len)

	{
		int ReturnLen = SUNSON_Read_Com_String(false, ucData);
		if (ReturnLen>0)
		{
			g_Log.WriteLog("SUNSON_SetDeviceInfo, 成功");
		}
		else
		{
			sprintf(csLog,"SUNSON_SetDeviceInfo, ReturnInfo = 0x%02X(失败)",ucData[0]);
			g_Log.WriteLog(csLog);
		}
		return ReturnLen;
	}
	else
	{
		sprintf(csLog,"SUNSON_SetDeviceInfo,failure! errorinfo = 0x%02x",ucData[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}

//民生银行版本指令 读取设备信息
int SUNSON_SerialGetDeviceInfo(unsigned char* DevName, unsigned char* EppName, unsigned char* EppNo, unsigned char* DriName)
{
	CCriticalSection autoSc;
	g_Log.WriteLog("---读取设备信息---");
	char csLog[1024] = {0};
	unsigned char ucData[256]={0};
	int i = 0;

	unsigned char ucCommand[12] = {0x1B,0x57,0x47,0x0d};
	i=SUNSON_SendDataToCom(ucCommand,4);
	if(i==4)
	{
		int ReturnLen = SUNSON_Read_Com_string_CMBC(false, ucData);
		if (ReturnLen>0)
		{
			memcpy(DevName, ucData, 10);
			memcpy(EppName, ucData+10, 20);
			memcpy(EppNo, ucData+30, 30);
			memcpy(DriName, ucData+60, 30);
			g_Log.WriteLog("SUNSON_GetDeviceInfo, 成功");
		}
		else
		{

			sprintf(csLog,"SUNSON_GetDeviceInfo, ReturnInfo = 0x%02X(失败)",ucData[0]);
			g_Log.WriteLog(csLog);
		}

		return ReturnLen;
	}
	else
	{
		sprintf(csLog,"SUNSON_GetDeviceInfo,failure! errorinfo = 0x%02x",ucData[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}

//导出SM2的EPPID和签名值 
int SUNSON_SerialExportSM2EppidAndSignData(unsigned char *SignAlg, int *nEppidLen, unsigned char *EPPID, int *SignLen, unsigned char *SignData, unsigned char* ReturnInfo)
{
	g_Log.WriteLog("---导出SM2的EPPID和签名值---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SerialExportSM2EppidAndSignData");
	g_Log.WriteLog(csLog);
	unsigned char ucData[2048]={0};
	int i = 0;
	
	unsigned char ucCommand[14] = {0x1B,0x45,0x45,0x00,0x02,0x00,0x00,0x0D,0x0A};
	for (i = 0; i < 6; i++)
	{
		ucCommand[6] ^= ucCommand[i];
	}
	i=SUNSON_SendDataToCom(ucCommand,9);
	if(i==9)
	{
		int ReturnLen = SUNSON_Read_Com_String(true, ucData);
		if (ReturnLen>0)
		{
			unsigned char temp[2046] = {0};
			unsigned char ucEppid[1024]  = {0};
			unsigned char ucSigndata[1024] = {0};
			hex_asc(ucData,temp,ReturnLen);
			//sprintf(csLog,"SUNSON_ExportSM2EppidAndSignData, ucData = %s",temp);
			//解析数据
			*SignAlg = 1;
			*nEppidLen = (ucData[1]<<8)|ucData[2];
			memcpy(EPPID, ucData+3, *nEppidLen);
			int nlen = 3+(*nEppidLen);
			*SignLen = (ucData[nlen]<<8)|ucData[nlen+1];
			memcpy(SignData, ucData+nlen+2, *SignLen);

			hex_asc(EPPID, ucEppid, *nEppidLen);
			hex_asc(SignData, ucSigndata, *SignLen);

			sprintf(csLog,"SUNSON_SerialExportSM2EppidAndSignData, EPPID = %s, SignData=%s",ucEppid, ucSigndata);
			g_Log.WriteLog(csLog);
		}
		else
		{
			ReturnInfo[0] = ucData[0];
			sprintf(csLog,"SUNSON_SerialExportSM2EppidAndSignData, ReturnInfo = 0x%02x(失败)",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		return ReturnLen;
	}
	else
	{
		ReturnInfo[0] = ucData[0];
		sprintf(csLog,"SUNSON_SerialExportSM2EppidAndSignData,failure! errorinfo = 0x%02x",ucData[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}

int SUNSON_SerialReadSN(unsigned char*SerialNumber)
{
	g_Log.WriteLog("---取EPP序列号---");
	g_Log.WriteLog("SUNSON_SerialReadSN");
	char csLog[1024] =
	{ 0 };
	*SerialNumber = 0x00;

	int i = 0;
	int nReturnValue = -1;
	unsigned char CommandData[8] =
	{ 0x1b, 0x52, 0x53, 0x00, 0x01, 0x00, 0x0d, 0x0a };
	CommandData[5] = CommandData[0] ^ CommandData[1] ^ CommandData[2]
			^ CommandData[3] ^ CommandData[4];
	i = SUNSON_SendDataToCom(CommandData, 8);
	if (i == 8)
	{
		nReturnValue = SUNSON_Read_Com_String(false, SerialNumber);
		if (nReturnValue > 0)
		{
			unsigned char temp[1024] =
			{ 0 };
			hex_asc(SerialNumber, temp, nReturnValue);
			sprintf(csLog, "SUNSON_SerialReadSN, sn = %s", temp);
			g_Log.WriteLog(csLog);
		}
		else
		{
			//unsigned char ResultInfo[2] =
			//{ 0 };
			sprintf(csLog, "SUNSON_SerialReadSN, ReturnInfo = 0x%02X(失败)",
					SerialNumber[0]);
			g_Log.WriteLog(csLog);
		}
		return nReturnValue;
	}
	else
	{
		sprintf(csLog, "SUNSON_SerialReadSN, send error ReturnInfo = 0x%02x(失败)",
				SerialNumber[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}

//usb-----
int sendUsbData(unsigned char* bSendBuf, int iSendLen, int iTimeOut)
{
    usleep(5000);
    int iRV = -1;
    int i = 0;
    unsigned char packcount = iSendLen/65;
    unsigned char remain = iSendLen%64;
    int count = 0;
    int actual = 0;
	if(dev_handle == NULL)
	{
		g_Log.WriteLog("dev_handle == NULL");
		return -1;
	}
    if(packcount > 0)
    {
        for(i=0;i<packcount;i++)
        {
             //iRV = libusb_interrupt_transfer(dev_handle, (1|LIBUSB_ENDPOINT_OUT), &bSendBuf[count], 64, &actual, iTimeOut);
	     iRV = libusb_bulk_transfer(dev_handle, (1|LIBUSB_ENDPOINT_OUT), &bSendBuf[count], 64, &actual, iTimeOut);
             if(iRV < 0)
             {
                 return iRV;
             }
             count += 64;
        }
    }
    if(remain > 0)
    {
        unsigned char temp[64];
        memset(temp,0x00,64);
        memcpy(temp,bSendBuf+count,remain);
        //iRV = libusb_interrupt_transfer(dev_handle, (1|LIBUSB_ENDPOINT_OUT), temp, 64, &actual, iTimeOut);
	iRV = libusb_bulk_transfer(dev_handle, (1|LIBUSB_ENDPOINT_OUT), temp, 64, &actual, iTimeOut);
        if(iRV < 0)
        {
        	char csLog[1024] ={ 0 };
        		sprintf(csLog,"iRV=%d", iRV);
        		g_Log.WriteLog(csLog);
            return iRV;
        }
    }
    return 0;
}

// 0 successful
//-1 timeout
//>0 epp return error code
int recvData(unsigned char* bRecvBuf, int* iRecvLen, int iTimeOut, int printfLog = 0);
int recvData(unsigned char* bRecvBuf, int* iRecvLen, int iTimeOut, int printfLog)
{
    unsigned char recvTemp[2048]={0};
    int count = 0;
    int nTemplen = 0;
    unsigned char recedata[65]={0};
    unsigned char recedata2[65]={0};
    int actual = 0;
    int iRV = -1;
    int nFlag = 0;
	if(dev_handle == NULL)
	{
		g_Log.WriteLog("dev_handle is NULL");
		return -1;
	}
    //iRV = libusb_interrupt_transfer(dev_handle, (1|LIBUSB_ENDPOINT_IN), recedata, 64, &actual, iTimeOut);
    iRV = libusb_bulk_transfer(dev_handle, (1|LIBUSB_ENDPOINT_IN), recedata, 64, &actual, iTimeOut);
    if(iRV < 0)
    {
    	char csLog[1024] ={ 0 };
    	 sprintf(csLog,"iRV=%d", iRV);
    	 g_Log.WriteLog(csLog);
        return iRV;
    }
    if(printfLog > 0)
    {
	char csLog[1024] ={ 0 };
    	 sprintf(csLog,"iRV=%d ,actual=%d, recedata=%02X%02X%02X%02X%02X%02X%02X%02X", iRV, actual,recedata[0],recedata[1],recedata[2],recedata[3],recedata[4],recedata[5],recedata[6],recedata[7]);
    	 g_Log.WriteLog(csLog);
    }


    if(actual == 64)
    {
        if(recedata[0] == 0x02)
        {
			if(recedata[1] == 0x45)
			{
				char csLog[1024] ={ 0 };
				   sprintf(csLog,"errorcode=%02x", recedata[4]);
				   g_Log.WriteLog(csLog);
				   bRecvBuf[0]=recedata[4];
				   nFlag = recedata[4]; //返回错误码
			}
			else if(recedata[1] == 0x53)
            {
				int nTemp1 = (recedata[2]&0xFF)*256;
				int nTemp2 = (recedata[3]&0xFF);
				nTemplen =  nTemp1 + nTemp2;
				char csLog[1024] ={ 0 };
				sprintf(csLog,"actual=%d, nTemplen=%d,recedata[2]=%02x, recedata[3]=%02x",
						actual, nTemplen, recedata[2], recedata[3]);
				if(printfLog > 0)
					g_Log.WriteLog(csLog);
				if(nTemplen+4 <= actual)
				{
					 memcpy(&recvTemp[count],recedata+4,nTemplen);
					 count += actual-4;
				}
				else
				{
					 memcpy(&recvTemp[count],recedata+4,actual-4); //减去包头4字节
					 count += actual-4;
				}
            }
        }
    }
    else
    {
    	char csLog[1024] ={ 0 };
    	sprintf(csLog,"short read actual=%d", actual);
        g_Log.WriteLog(csLog);
        return -1;    //short read
    }
    if(count < nTemplen)
    {
        for (int i = count; i < nTemplen; i += 64)
        {
            iRV = libusb_bulk_transfer(dev_handle, (1|LIBUSB_ENDPOINT_IN), recedata, 64, &actual, 1000);
            if(iRV < 0)
            {
            	char csLog[1024] ={ 0 };
            	    	 sprintf(csLog,"iRV2=%d", iRV);
            	    	 g_Log.WriteLog(csLog);
                return iRV;
            }
            if(actual == 64)
            {
                 memcpy(&recvTemp[count],recedata,actual);
                count += actual;
            }
            else
            {
		char csLog[1024] ={ 0 };
    		sprintf(csLog,"empty actual=%d", actual);
        	g_Log.WriteLog(csLog);
                return -1;
            }
        }
    }

  //  g_Log.WriteLog("read empty pack");
    libusb_bulk_transfer(dev_handle, (1|LIBUSB_ENDPOINT_IN), recedata2, 64, &actual, 100);
	if(recedata2[1] != 0x00)
	{
		char csLog[1024] ={ 0 };
		 sprintf(csLog,"recedata2=%02x", recedata2[1]);
		 g_Log.WriteLog(csLog);
		 nFlag = recedata2[1];  //error code
	}

    memcpy(bRecvBuf, recvTemp, nTemplen);
   
    *iRecvLen = nTemplen;
    return nFlag;
}

// 0 successful
//-1 timeout
//>0 epp return error code
int recvDataCMBC(unsigned char* bRecvBuf, int* iRecvLen, int iTimeOut)
{
    unsigned char recvTemp[2048]={0};
    int count = 0;
    int nTemplen = 0;
    unsigned char recedata[65]={0};
    unsigned char recedata2[65]={0};
    int actual = 0;
    int iRV = -1;
    int nFlag = 0;
	if(dev_handle == NULL)
	{
		g_Log.WriteLog("dev_handle is NULL");
		return -1;
	}
    iRV = libusb_interrupt_transfer(dev_handle, (1|LIBUSB_ENDPOINT_IN), recedata, 64, &actual, iTimeOut);
    if(iRV < 0)
    {
    	char csLog[1024] ={ 0 };
    	 sprintf(csLog,"iRV=%d", iRV);
    	 g_Log.WriteLog(csLog);
        return iRV;
    }
    if(actual == 64)
    {
        if(recedata[0] == 0x02)
        {
			if(recedata[1] == 0x45)
			{
				char csLog[1024] ={ 0 };
				   sprintf(csLog,"errorcode=%02x", recedata[4]);
				   g_Log.WriteLog(csLog);
				   bRecvBuf[0]=recedata[4];
				   nFlag = recedata[4]; //返回错误码
			}
			//else if(recedata[1] == 0x53)
            {
				//int nTemp1 = (recedata[2]&0xFF)*256;
				//int nTemp2 = (recedata[3]&0xFF);
				nTemplen =  63;
				char csLog[1024] ={ 0 };
				sprintf(csLog,"actual=%d, nTemplen=%d,recedata[2]=%02x, recedata[3]=%02x",
						actual, nTemplen, recedata[2], recedata[3]);
				//g_Log.WriteLog(csLog);
				//if(nTemplen+4 <= actual)
				{
					 memcpy(&recvTemp[count],recedata+1,nTemplen);
					 count += nTemplen;
				}
				//else
				//{
				//	 memcpy(&recvTemp[count],recedata+4,actual-4); //减去包头4字节
				//	 count += actual-4;
				//}
            }
        }
    }
    else
    {
    	char csLog[1024] ={ 0 };
    	sprintf(csLog,"short read actual=%d", actual);
        g_Log.WriteLog(csLog);
        return -1;    //short read
    }
   // if(count < nTemplen)
    {
    //    for (int i = count; i < nTemplen; i += 64)
        {
            iRV = libusb_interrupt_transfer(dev_handle, (1|LIBUSB_ENDPOINT_IN), recedata, 64, &actual, 1000);
            if(iRV < 0)
            {
            	char csLog[1024] ={ 0 };
            	    	 sprintf(csLog,"iRV2=%d", iRV);
            	    	 g_Log.WriteLog(csLog);
                return iRV;
            }
            if(actual == 64)
            {
                 memcpy(&recvTemp[count],recedata,actual);
                count += actual;
            }
            else
            {
                return -1;
            }
        }
    }

  //  g_Log.WriteLog("read empty pack");
    libusb_interrupt_transfer(dev_handle, (1|LIBUSB_ENDPOINT_IN), recedata2, 64, &actual, 100);
	if(recedata2[1] != 0x00)
	{
		char csLog[1024] ={ 0 };
		 sprintf(csLog,"recedata2=%02x", recedata2[1]);
		 g_Log.WriteLog(csLog);
		 nFlag = recedata2[1];  //error code
	}

    memcpy(bRecvBuf, recvTemp, nTemplen);
   
    *iRecvLen = nTemplen;
    return nFlag;
}

int recv_onepack(unsigned char* bRecvBuf, int* iRecvLen, int iTimeOut)
{
    int count = 0;
    unsigned char recedata[64]={0};
    unsigned char recedata2[64]={0};
    int actual = 0;
    int iRV = -1;
    int nFlag = 0;
	
	if(dev_handle == NULL)
	{
		return -1;
	}
    iRV = libusb_interrupt_transfer(dev_handle, (1|LIBUSB_ENDPOINT_IN), recedata, 64, &actual, iTimeOut);
    if(iRV < 0)
    {
        return iRV;
    }
    if(actual == 64)
    {
        if(recedata[0] == 0x02)
        {
        	int nTemp1 = (recedata[2]&0xFF)*256;
        	int nTemp2 = (recedata[3]&0xFF);
        	int len = nTemp1+nTemp2;
        	memcpy(bRecvBuf,recedata+4,len);
        	count = len;
			if(recedata[1] == 0x53)
			{
				nFlag = 0;
			}
			else if(recedata[1] == 0x45)
			{
				bRecvBuf[0]=recedata[4];
				nFlag = recedata[4]; //返回错误码
			}
        }
        else
            return -1;
    }
    else
    {
        return -1;
    }
    
   // g_Log.WriteLog("read empty pack");
    libusb_interrupt_transfer(dev_handle, (1|LIBUSB_ENDPOINT_IN), recedata2, 64, &actual, 100);
	if(recedata2[1] != 0x00)
	{
		nFlag = recedata2[1];  //error code
	}

    *iRecvLen = count;
    return nFlag;
}
// 0 successful
//-1 timeout
//>0 epp return error code
int recv_ST(unsigned char* bRecvBuf, int* iRecvLen, int iTimeOut)
{
    int count = 0;
    unsigned char recedata[64]={0};
    unsigned char recedata2[64]={0};
    int actual = 0;
    int iRV = -1;
    int nFlag = 0;
	
	if(dev_handle == NULL)
	{
		return -1;
	}
    iRV = libusb_interrupt_transfer(dev_handle, (1|LIBUSB_ENDPOINT_IN), recedata, 64, &actual, iTimeOut);
    if(iRV < 0)
    {
        return iRV;
    }
    if(actual == 64)
    {
        if(recedata[0] == 0x02)
        {
        	int nTemp1 = (recedata[2]&0xFF)*256;
        	int nTemp2 = (recedata[3]&0xFF);
        	int len = nTemp1+nTemp2;
        	memcpy(bRecvBuf,recedata+4,len);
        	count = len;
            //memcpy(bRecvBuf,recedata+4,actual-4);
            //count += actual;
			if(recedata[1] == 0x53)
			{
				nFlag = 0;
			}
			if(recedata[1] == 0x45)
			{
				bRecvBuf[0]=recedata[4];
				nFlag = recedata[4]; //返回错误码
			}
        }
		else
		{
			return -1;
		}
    }
    else
    {
        return -1;
    }
    
   // g_Log.WriteLog("read empty pack");
    libusb_interrupt_transfer(dev_handle, (1|LIBUSB_ENDPOINT_IN), recedata2, 64, &actual, 100);
	if(recedata2[1] != 0x00)
	{
		nFlag = recedata2[1];  //error code
	}

    *iRecvLen = count;
    return nFlag;
}
int recv_STFA1(unsigned char* bRecvBuf, int* iRecvLen, int iTimeOut)
{
    int count = 0;
    unsigned char recedata[64]={0};
    //unsigned char recedata2[64]={0};
    int actual = 0;
    int iRV = -1;
    int nFlag = 0;
	
	if(dev_handle == NULL)
	{
		return -1;
	}
    iRV = libusb_interrupt_transfer(dev_handle, (1|LIBUSB_ENDPOINT_IN), recedata, 64, &actual, iTimeOut);
    if(iRV < 0)
    {
        return iRV;
    }
    if(actual == 64)
    {
        if(recedata[0] == 0x1b)
        {
        	int nTemp1 = (recedata[2]&0xFF)*256;
        	int nTemp2 = (recedata[3]&0xFF);
        	int len = nTemp1+nTemp2;
        	memcpy(bRecvBuf,recedata,len+6);
        	count = len+6;
		
        }
    }
    else
    {
        return -1;
    }

    *iRecvLen = count;
    return nFlag;
}


void DataOperation(unsigned char* CurrentKey_Data, unsigned char len,
		unsigned char*Source_Data, unsigned char*Result_Data,
		unsigned char flag)
{
	unsigned char Source[8];
	memset(Source, 0, 8);
	unsigned char Dest[8];
	memset(Dest, 0, 8);
	int j = 0;
	int k = 0;
	int m = 0;
	for (int i = 0; i < len; i++)
	{
		for (k = 0; k < 8; k++)
			Source[k] = Source_Data[k + j * 8];
		TDES_FUN(Source, Dest, CurrentKey_Data, flag, 2);
		for (m = 0; m < 8; m++)
			Result_Data[m + j * 8] = Dest[m];
		j++;
	}
}

//Open the serial port
int SUNSON_OpenCom(const char *sztty, long nBaudrate)
{
	g_Log.WriteLog("F31--COM&&USB--20220629-");
	g_IsCom = false;
	if(strcasecmp(sztty, "USB") != 0)
	{
		g_IsCom = true;
		return SUNSON_SerialOpenCom(sztty, nBaudrate);
	}
g_mutex.Lock();
	char CLog[1024] = { 0 };
	g_Log.WriteLog("***open USB***");
	sprintf(CLog, "SUNSON_OpenCom,sztty = %s,nBaudrate = %d", sztty,
			(int) nBaudrate);
	g_Log.WriteLog(CLog);

	libusb_device **devs;
        ssize_t cnt;
        int r;

        r = libusb_init(&ctx); //initialize a library session
        if(r < 0) {
            g_Log.WriteLog("Init Error\n");//there was an error
	    g_mutex.Unlock(); 
            return 0;
        }
        //libusb_set_debug(ctx, 3);
        cnt = libusb_get_device_list(ctx, &devs); //get the list of devices
        if(cnt < 0)
        {
	    libusb_exit(ctx);
            g_Log.WriteLog("Get Device Error\n"); //there was an error
	    g_mutex.Unlock(); 
            return 0;
        }
        r = foundusbdev(devs,cnt);
        if(r != 0)
        {
	    libusb_exit(ctx);
            g_Log.WriteLog("Not found usb device\n");
	    g_mutex.Unlock();
            return 0;
        }
        dev_handle = libusb_open_device_with_vid_pid(ctx, 0x0483, 0x3021);
        if(dev_handle == NULL)
        {
            libusb_exit(ctx);
            g_Log.WriteLog("libusb_open_device_with_vid_pid error\n");
	    g_mutex.Unlock();
            return 0;
        }
		
        if(libusb_kernel_driver_active(dev_handle, 0) == 1)
        {
            libusb_detach_kernel_driver(dev_handle, 0);
        }
        r = libusb_claim_interface(dev_handle, 0);
	g_Log.WriteLog("打开USB成功！");
		g_SendCmd = 1; //被动模式
		g_mutex.Unlock();  
	

	return 1;
}

//Close the serial port
int SUNSON_CloseCom(void)
{
	if(g_IsCom)
	{
		return SUNSON_SerialCloseCom();
	}
	g_Log.WriteLog("***关闭USB***");
	if(dev_handle != NULL)
	{
		
	    libusb_release_interface(dev_handle, 0);
		g_Log.WriteLog("libusb_release_interface");		
	    libusb_attach_kernel_driver(dev_handle, 0);
		g_Log.WriteLog("libusb_attach_kernel_driver");
	    libusb_close(dev_handle);
		g_Log.WriteLog("libusb_close");
	    libusb_exit(ctx);
	}
	dev_handle = NULL;
	g_Log.WriteLog("关闭USB成功！");
	return 1;
}

//获取按下的按键键值
int SUNSON_ScanKeyPress(unsigned char *ucKeyValue)
{
	if(g_IsCom)
	{
		return SUNSON_SerialScanKeyPress(ucKeyValue);
	}
	g_mutex.Lock();
	
		int nReturnValue = -1;
		unsigned char CommandData[8]={0x1b,0x47,0x55,0x00,0x01,0x08,0x0D,0x0A};
		unsigned char keyvalue[256];
		memset(keyvalue,0,256);
		int len = sendUsbData(CommandData,8,1000);
		if(len==0)
		{
			int nRetlen = 0;
			nReturnValue=recvData(keyvalue, &nRetlen, 1000);
			if(nReturnValue == 0)
			{
				ucKeyValue[0]=keyvalue[0]; 
				if (keyvalue[0] == 0xFF)
				{
					g_mutex.Unlock();   
					return 0;
				}
				 
				char csLog[256] = {0};
				sprintf(csLog,"SUNSON_ScanKeyPress,ucValue = %02x",ucKeyValue[0]);
				g_Log.WriteLog(csLog);
				g_mutex.Unlock();   
				return 1;
			}
		}
		g_mutex.Unlock(); 
		return 0;
}

int SUNSON_ScanGetKey(unsigned char *ucKeyValue) //被动模式获取键值，发送指令从键盘读取键值
{
	if(g_IsCom)
	{
		return SUNSON_SerialScanGetKey(ucKeyValue);
	}
	g_mutex.Lock();
	//unsigned char ResultInfo[256] = {0};
	char csLog[1024] = {0};

	int i=0;
	int nReturnValue=-1;
	unsigned char CommandData[9]={0x1b,0x47,0x55,0x00,0x01,0x08,0x0D,0x0A};
	
	i=sendUsbData(CommandData,8,1000);
	if(i==0)
	{
		int nRetlen = 0;
		unsigned char keyvalue[256]={0};
		nReturnValue=recvData(keyvalue, &nRetlen, 1000);
		if(nReturnValue == 0)
		{
			if (keyvalue[0] == 0xFF)
			{
				g_mutex.Unlock();   
				return 0;
			}
			ucKeyValue[0]=keyvalue[0];  
			char csLog[256] = {0};
			sprintf(csLog,"SUNSON_ScanGetKey,ucValue = %02x",ucKeyValue[0]);
			g_Log.WriteLog(csLog);
			g_mutex.Unlock();   
			return 1;
		}		
	}
	else 
	{
		ucKeyValue[0] = 0xFB; 
		sprintf(csLog,"SUNSON_ScanGetKey, 指令发送失败");
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
	
	return 0;
}

//获取操作执行后的错误信息或成功标志信息
int SUNSON_GetOperationResult(unsigned char *ucResultInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialGetOperationResult(ucResultInfo);
	}
	return 0;
	int nLen = 0;
	int flag = recv_ST(ucResultInfo, &nLen, 1000);
	return flag;

}
/*********************************************************************
 与密码键盘相关指令封装
 **********************************************************************/
//B.1取EPP键盘版本号
int SUNSON_GetVersionNo(unsigned char*VersionNo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialGetVersionNo(VersionNo);
	}
	g_mutex.Lock();
	if(g_nLogLevel >0)
		g_Log.WriteLog("---取键盘版本号---");
	char csLog[1024] ={ 0 };
	sprintf(csLog, "SUNSON_GetVersionNo-0609");
	if(g_nLogLevel>0)
		g_Log.WriteLog(csLog);
	*VersionNo = 0x00;

	int i = 0;
	int nReturnValue = -1;
	unsigned char CommandData[8] =
	{ 0x1b, 0x52, 0x45, 0x00, 0x01, 0x00, 0x0d, 0x0a };
	CommandData[5] = CommandData[0] ^ CommandData[1] ^ CommandData[2]
	^ CommandData[3] ^ CommandData[4];
	i = sendUsbData(CommandData, 8, 1000);
	if (i == 0)
	{
		int nRetlen = 0;
		nReturnValue = recvData(VersionNo, &nRetlen, 2000);
		nReturnValue = nRetlen;
		if (nReturnValue > 0)
		{
			unsigned char temp[1024] =
			{ 0 };
			hex_asc(VersionNo, temp, nReturnValue);
			sprintf(csLog, "SUNSON_GetVersionNo, DataResult = %s", temp);
			if(g_nLogLevel>0)
				g_Log.WriteLog(csLog);
		}
		else
		{
			unsigned char ResultInfo[2] =
			{ 0 };
			hex_asc_char(VersionNo[0], ResultInfo);
			sprintf(csLog, "SUNSON_GetVersionNo, ReturnInfo = 0x%c%c(失败)",
				ResultInfo[0], ResultInfo[1]);
			g_Log.WriteLog(csLog);
		}
		g_mutex.Unlock(); 
		return nReturnValue;
	}
	else
	{
		sprintf(csLog, "SUNSON_GetVersionNo, ReturnInfo = 0x%02x(失败)",
			VersionNo[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}
//B.2系统复位
int SUNSON_ResetEpp(unsigned char *errorinfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialResetEpp(errorinfo);
	}
	g_mutex.Lock();
	g_Log.WriteLog("---系统复位---");
	char csLog[1024] =
	{ 0 };
	sprintf(csLog, "SUNSON_ResetEpp");
	g_Log.WriteLog(csLog);
	*errorinfo = 0x00;

	int i = 0;
	int nReturnValue = -1;
	unsigned char CommandData[8] =
	{ 0x1b, 0x53, 0x46, 0x00, 0x01, 0x00, 0x0d, 0x0a };
	CommandData[5] = CommandData[0] ^ CommandData[1] ^ CommandData[2]
			^ CommandData[3] ^ CommandData[4];
	i = sendUsbData(CommandData, 8, 1000);
	if (i == 0)
	{
		int nLen = 0;
		nReturnValue = recv_ST(errorinfo, &nLen, 1000);
		if (nReturnValue == 0)
		{
			g_Log.WriteLog("SUNSON_ResetEpp,success!");
		}
		else
		{
			sprintf(csLog, "SUNSON_ResetEpp,failure! errorinfo = 0x%02x",
					errorinfo[0]);
			g_Log.WriteLog(csLog);
			g_mutex.Unlock(); 
			return 0;
		}
		g_mutex.Unlock(); 
		return nLen;
	}
	else
	{
		sprintf(csLog, "SUNSON_ResetEpp,failure! errorinfo = 0x%02x",
				errorinfo[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}
//B.3自定义按键标志属性
int SUNSON_SetKeyMark(long ActiveFunc, long ActiveFDK, long EndFunc,
		long EndFDK, unsigned char*errorinfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialSetKeyMark(ActiveFunc, ActiveFDK, EndFunc, EndFDK, errorinfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---自定义按键标志属性---");
	char csLog[1024] =
	{ 0 };
	sprintf(csLog,"SUNSON_SetKeyMark,ActiveFunc = %ld,ActiveFDK = %ld,EndFunc = %ld,EndFDK = %ld",
			ActiveFunc, ActiveFDK, EndFunc, EndFDK);
	g_Log.WriteLog(csLog);
	*errorinfo = 0x00;

	int i = 0;
	int nReturnValue = -1;
	unsigned char data[4];
	memset(data, 0, 4);
	unsigned char CommandData[24];
	unsigned char XOR = 0x00;
	CommandData[0] = 0x1b;
	CommandData[1] = 0x53;
	CommandData[2] = 0x4B;
	CommandData[3] = 0x00;
	CommandData[4] = 0x11;

	for (int m = 0; m < 4; m++)
	{
		data[m] = (unsigned char) (((ActiveFunc) >> (8 * m)) & 0xFF);
	}
	CommandData[5] = data[0];
	CommandData[6] = data[1];
	CommandData[7] = data[2];
	CommandData[8] = data[3];

	for (int m = 0; m < 4; m++)
	{
		data[m] = (unsigned char) (((ActiveFDK) >> (8 * m)) & 0xFF);
	}
	CommandData[9] = data[0];
	CommandData[10] = data[1];
	CommandData[11] = data[2];
	CommandData[12] = data[3];

	for (int m = 0; m < 4; m++)
	{
		data[m] = (unsigned char) (((EndFunc) >> (8 * m)) & 0xFF);
	}
	CommandData[13] = data[0];
	CommandData[14] = data[1];
	CommandData[15] = data[2];
	CommandData[16] = data[3];

	for (int m = 0; m < 4; m++)
	{
		data[m] = (unsigned char) (((EndFDK) >> (8 * m)) & 0xFF);
	}
	CommandData[17] = data[0];
	CommandData[18] = data[1];
	CommandData[19] = data[2];
	CommandData[20] = data[3];

	for (i = 0; i < 21; i++)
	{
		XOR ^= CommandData[i];
	}
	CommandData[21] = XOR;
	CommandData[22] = 0x0d;
	CommandData[23] = 0x0a;
	i = sendUsbData(CommandData, 24, 1000);
	if (i == 0)
	{
		int nLen = 0;
		nReturnValue = recv_ST(errorinfo, &nLen, 1000);
		if (nReturnValue == 0)
		{
			g_Log.WriteLog("SUNSON_SetKeyMark,success!");
		}
		else
		{
			sprintf(csLog, "SUNSON_SetKeyMark,failure! errorinfo = 0x%02x",
					errorinfo[0]);
			g_Log.WriteLog(csLog);
		}
		g_mutex.Unlock(); 
		return nLen;
	}
	else
	{
		sprintf(csLog, "SUNSON_SetKeyMark,failure! errorinfo = 0x%02x",
				errorinfo[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}

//B.4读取密钥校验值
/*
 #define WFS_PIN_KCVNONE (0x0000)
 #define WFS_PIN_KCVSELF (0x0001)
 #define WFS_PIN_KCVZERO (0x0002)
 //*/
int SUNSON_GetCheckValue(unsigned char ucCheckMode, unsigned char *CheckValue)
{
	if(g_IsCom)
	{
		return SUNSON_SerialGetCheckValue(ucCheckMode, CheckValue);
	}
g_mutex.Lock();
	g_Log.WriteLog("---读取密钥校验值---");
	char csLog[1024] =
	{ 0 };
	sprintf(csLog, "SUNSON_GetCheckValue,mode = %02x", ucCheckMode);
	g_Log.WriteLog(csLog);
	*CheckValue = 0x00;

	int i = 0;
	int nReturnValue = -1;
	unsigned char CommandData[10] =
	{ 0x1b, 0x52, 0x43, 0x00, 0x02, 0x00, 0x00, 0x0d, 0x0a };
	CommandData[5] = ucCheckMode;
	CommandData[6] = CommandData[0] ^ CommandData[1] ^ CommandData[2]
			^ CommandData[3] ^ CommandData[4] ^ CommandData[5];
	i = sendUsbData(CommandData, 9, 1000);
	if (i == 0)
	{
		int nRetlen = 0;
		nReturnValue = recvData(CheckValue, &nRetlen, 2000);
		nReturnValue = nRetlen;
		if (nReturnValue > 0)
		{
			unsigned char temp[1024] =
			{ 0 };
			hex_asc(CheckValue, temp, nReturnValue);
			sprintf(csLog, "SUNSON_GetCheckValue, CheckValue = %s", temp);
			g_Log.WriteLog(csLog);
		}
		else
		{
			unsigned char ResultInfo[2] =
			{ 0 };
			hex_asc_char(CheckValue[0], ResultInfo);
			sprintf(csLog, "SUNSON_GetCheckValue, ReturnInfo = 0x%c%c(失败)",
					ResultInfo[0], ResultInfo[1]);
			g_Log.WriteLog(csLog);
		}
		g_mutex.Unlock(); 
		return nReturnValue;
	}
	else
	{
		sprintf(csLog, "SUNSON_GetCheckValue, ReturnInfo = 0x%02x(失败)",
				CheckValue[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}

//B.5下载用户密钥
/*
 #define WFS_PIN_USECRYPT     (0x0001)
 #define WFS_PIN_USEFUNCTION  (0x0002)
 #define WFS_PIN_USEMACING    (0x0004)
 #define WFS_PIN_USEKEYENCKEY (0x0020)
 */
int SUNSON_LoadUserKey(int ucKeyId, int ucDecryptKeyId, unsigned char KeyAttribute,
		unsigned char ucKeyLen, unsigned char *KeyValue,
		unsigned char *ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialLoadUserKey(ucKeyId, ucDecryptKeyId, KeyAttribute, ucKeyLen, KeyValue, ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---下载用户密钥---");
	char csLog[1024] =
	{ 0 };
	sprintf(
			csLog,
			"SUNSON_LoadUserKey,KeyId1 = %02x,KeyId2 = %02x,KeyAtt = %02x,keyValueLength = %d",
			ucKeyId, ucDecryptKeyId, KeyAttribute, ucKeyLen);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	if(g_bLogClearSecret == false)
	{
		unsigned char temp[256]={0};
		hex_asc(KeyValue, temp, ucKeyLen);
		sprintf(csLog, "Keyvalue=%s", (char*)temp);
		g_Log.WriteLog(csLog);
	}

	int i = 0;
	int nReturnValue = -1;
	unsigned char CommandData[256];
	memset(CommandData, 0, 256);
	unsigned char data[4];
	memset(data, 0, 4);
	CommandData[0] = 0x1b;
	CommandData[1] = 0x4c;
	CommandData[2] = 0x4b;
	CommandData[3] = 0x00;
	CommandData[4] = 0x16;
	CommandData[5] = ucKeyId / 256;
	CommandData[6] = ucKeyId % 256;
	CommandData[7] = ucDecryptKeyId / 256;
	CommandData[8] = ucDecryptKeyId % 256;
	CommandData[9]=KeyAttribute;
	if (ucKeyLen == 8)
	{
		for (int m = 0; m < 2; m++)
		{
			for (i = 0; i < 8; i++)
			{
				CommandData[10 + i + m * 8] = KeyValue[i];
			}
		}
		ucKeyLen = 16;
	}
	else if (ucKeyLen == 16)
	{
		for (i = 0; i < 16; i++)
		{
			CommandData[10 + i] = KeyValue[i];
		}
	}
	else if (ucKeyLen == 24)
	{
		for (i = 0; i < 24; i++)
		{
			CommandData[10 + i] = KeyValue[i];
		}
	}
	else
	{
		g_mutex.Unlock(); 
		return 0;
	}

	CommandData[3] = (ucKeyLen+6)/256;
	CommandData[4] = (ucKeyLen+6)%256;

	for(i=0;i<(10+ucKeyLen);i++)
		CommandData[10+ucKeyLen]^=CommandData[i];
	CommandData[11+ucKeyLen]=0x0d;
	CommandData[12+ucKeyLen]=0x0a;
	i = sendUsbData(CommandData, 13+ucKeyLen, 1000);
	if (i == 0)
	{
		int nLen = 0;
		nReturnValue = recv_ST(ReturnInfo, &nLen, 1000);
		if (nReturnValue == 0)
		{
			g_Log.WriteLog("SUNSON_LoadUserKey,success!");
		}
		else
		{
			sprintf(csLog, "SUNSON_LoadUserKey,failure! errorinfo = 0x%02x",
					ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		g_mutex.Unlock(); 
		return nLen;
	}
	else
	{
		sprintf(csLog, "SUNSON_LoadUserKey,failure! errorinfo = 0x%02x",
				ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}



//B.6删除所有密钥
int SUNSON_DeleteAllKeys(unsigned char *ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialDeleteAllKeys(ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---删除所有密钥---");
	char csLog[1024] =
	{ 0 };
	sprintf(csLog, "SUNSON_DeleteAllKeys");
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	int i = 0;
	int nReturnValue = -1;
	unsigned char CommandData[8] =
	{ 0x1b, 0x44, 0x41, 0x00, 0x01, 0x00, 0x0d, 0x0a };
	for (i = 0; i < 5; i++)
		CommandData[5] ^= CommandData[i];
	i = sendUsbData(CommandData, 8, 1000);
	if (i == 0)
	{
		sleep(3);
		int nLen = 0;
		nReturnValue = recv_ST(ReturnInfo, &nLen, 2000);
		if (nReturnValue ==0)
		{
			g_Log.WriteLog("SUNSON_DeleteAllKeys,success!");
		}
		else
		{
			sprintf(csLog, "SUNSON_DeleteAllKeys,failure! errorinfo = 0x%02x",
					ReturnInfo[0]);
			g_Log.WriteLog(csLog);
			g_mutex.Unlock(); 
			return 0;
		}
		g_mutex.Unlock(); 
		return nLen;
	}
	else
	{
		sprintf(csLog, "SUNSON_DeleteAllKeys,failure! errorinfo = 0x%02x",
				ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}
//B.7删除指定用户密钥
int SUNSON_DelSpecialUserKey(int UserKeyId, unsigned char *ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialDelSpecialUserKey(UserKeyId, ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---删除指定用户密钥---");
	char csLog[1024] =
	{ 0 };
	sprintf(csLog, "SUNSON_DelSpecialUserKey,UserKeyId = %d", UserKeyId);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	int i = 0;
	int nReturnValue = -1;
	unsigned char CommandData[10] =
	{ 0x1b, 0x44, 0x44, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0d, 0x0a };
	CommandData[5] = UserKeyId / 256;
	CommandData[6] = UserKeyId % 256;
	for (i = 0; i < 7; i++)
		CommandData[7] ^= CommandData[i];
	i = sendUsbData(CommandData, 10, 1000);
	if (i == 0)
	{
		int nLen = 0;
		nReturnValue = recv_ST(ReturnInfo, &nLen, 1000);
		if (nReturnValue == 0)
		{
			g_Log.WriteLog("SUNSON_DelSpecialUserKey,success!");
		}
		else
		{
			sprintf(csLog,
					"SUNSON_DelSpecialUserKey,failure! errorinfo = 0x%02x",
					ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		g_mutex.Unlock(); 
		return nLen;
	}
	else
	{
		sprintf(csLog, "SUNSON_DelSpecialUserKey,failure! errorinfo = 0x%02x",
				ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}

//B.8蜂鸣器使能
int SUNSON_SetBuzzerEnabled(unsigned char ucBuzzerStatus,
							unsigned char *ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialSetBuzzerEnabled(ucBuzzerStatus, ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---蜂鸣器使能---");
	char csLog[1024] =
	{ 0 };
	sprintf(csLog, "SUNSON_SetBuzzerEnabled,beep = %02x", ucBuzzerStatus);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	int i = 0;
	int nReturnValue = -1;
	unsigned char CommandData[9] =
	{ 0x1b, 0x53, 0x5a, 0x00, 0x02, 0x00, 0x00, 0x0d, 0x0a };
	CommandData[5] = ucBuzzerStatus;
	for (i = 0; i < 6; i++)
		CommandData[6] ^= CommandData[i];
	i = sendUsbData(CommandData, 9,1000);
	if (i == 0)
	{
		int nLen = 0;
		nReturnValue = recv_ST(ReturnInfo, &nLen, 1000);
		if (nReturnValue == 0)
		{
			g_Log.WriteLog("SUNSON_SetBuzzerEnabled,success!");
		}
		else
		{
			sprintf(csLog,
				"SUNSON_SetBuzzerEnabled,failure! errorinfo = 0x%02x",
				ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		g_mutex.Unlock(); 
		return nLen;
	}
	else
	{
		sprintf(csLog, "SUNSON_SetBuzzerEnabled,failure! errorinfo = 0x%02x",
			ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}
//B.9 设定初始向量
int SUNSON_SetStartValue(unsigned char *StartValue, unsigned char *ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialSetStartValue(StartValue, ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---设定初始向量---");
	char csLog[1024] =
	{ 0 };
	unsigned char temp[1024] =
	{ 0 };
	hex_asc(StartValue, temp, 8);
	sprintf(csLog, "SUNSON_SetStartValue,vector = %s", temp);
	if(g_bLogClearSecret == false)
		g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	unsigned char CommandData[16];
	memset(CommandData, 0, 16);
	int nReturnValue = -1;
	CommandData[0] = 0x1b;
	CommandData[1] = 0x44;
	CommandData[2] = 0x56;
	CommandData[3] = 0x00;
	CommandData[4] = 0x09;
	for (int i = 0; i < 8; i++)
		CommandData[5 + i] = StartValue[i];
	for (int i = 0; i < 13; i++)
		CommandData[13] ^= CommandData[i];
	CommandData[14] = 0x0d;
	CommandData[15] = 0x0a;
	int i = sendUsbData(CommandData, 16,1000);
	if (i == 0)
	{
		int nLen = 0;
		nReturnValue = recv_ST(ReturnInfo, &nLen, 1000);
		if (nReturnValue == 0)
		{
			g_Log.WriteLog("SUNSON_SetStartValue,success!");
		}
		else
		{
			sprintf(csLog, "SUNSON_SetStartValue,failure! errorinfo = 0x%02x",
					ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		g_mutex.Unlock(); 
		return nLen;
	}
	else
	{
		sprintf(csLog, "SUNSON_SetStartValue,failure! errorinfo = 0x%02x",
				ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;

	}
}

int SUNSON_SetStartValueEx(int nDataLen,unsigned char *StartValue,unsigned char *ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialSetStartValueEx(nDataLen, StartValue, ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---设定初始向量Ex---");
	char csLog[1024] = {0};
	char temp[1024] = {0};
	hex_asc(StartValue, (unsigned char*)temp, nDataLen);
	sprintf(csLog,"SUNSON_SetStartValueEx,nlen = %d,vector = %s", nDataLen,temp);
	if(g_bLogClearSecret == false)
		g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	unsigned char CommandData[256];
	memset(CommandData,0,256);
	int nReturnValue=-1;
	CommandData[0]=0x1b;
	CommandData[1]=0x44;
	CommandData[2]=0x56;
	CommandData[3]=0x00;
	CommandData[4]=0x01+nDataLen;
	for(int i=0;i<nDataLen;i++)
		CommandData[5+i]=StartValue[i];
	for(int i=0;i<5+nDataLen;i++)
		CommandData[5+nDataLen]^=CommandData[i];
	CommandData[6+nDataLen]=0x0d;   
	CommandData[7+nDataLen]=0x0a;

	int i=sendUsbData(CommandData,8+nDataLen,1000);
	if(i==0)
	{
		int nLen = 0;
		nReturnValue=recv_ST(ReturnInfo, &nLen, 1000);
		if (nReturnValue ==0)
		{
			g_Log.WriteLog("SUNSON_SetStartValueEx,success!");
		}
		else
		{
			sprintf(csLog,"SUNSON_SetStartValueEx,failure! errorinfo = 0x%02x",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		g_mutex.Unlock(); 
		return nLen;			
	}
	else
	{
		sprintf(csLog,"SUNSON_SetStartValueEx,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}

//B.10数据运算
/* JM_mode
 #define WFS_PIN_MODEENCRYPT (1)
 #define WFS_PIN_MODEDECRYPT (2)
 //////////////////////////////////
 SF_mode
 #define WFS_PIN_CRYPTDESECB (0x0001)
 #define WFS_PIN_CRYPTDESCBC (0x0002)
 #define WFS_PIN_CRYPTDESCFB (0x0004)
 #define WFS_PIN_CRYPTRSA    (0x0008)
 #define WFS_PIN_CRYPTECMA   (0x0010)
 #define WFS_PIN_CRYPTDESMAC (0x0020)
 #define WFS_PIN_CRYPTTRIDESECB (0x0040)
 #define WFS_PIN_CRYPTTRIDESCBC (0x0080)
 #define WFS_PIN_CRYPTTRIDESCFB (0x0100)
 #define WFS_PIN_CRYPTTRIDESMAC (0x0200)
 #define WFS_PIN_CRYPTMAAMAC    (0x0400)
 */////////////////////////////////////////
int SUNSON_DataCompute(int KeyId, unsigned char JM_mode, unsigned char SF_mode,
		unsigned char padchar, int datalen, unsigned char *data,
		unsigned char *DataResult)
{
	if(g_IsCom)
	{
		return SUNSON_SerialDataCompute(KeyId, JM_mode, SF_mode, padchar, datalen, data, DataResult);
	}
g_mutex.Lock();
	int i = 0;
	g_Log.WriteLog("---数据运算---");
	char csLog[4096] =
	{ 0 };
	unsigned char temp[2048] =
	{ 0 };
	if(datalen > 1024)
	{
		g_Log.WriteLog("Data数据超出1K限制!");
		g_mutex.Unlock(); 
		return 0;
	}

	//兼容F35的调用，如果按照F35参数传，则做个转换
	if(JM_mode == 0x01)
		{
			JM_mode = 0x31; //数据加密
		}
	else if(JM_mode == 0x02)
		{
			JM_mode = 0x30; //数据解密
		}
		
	if(SF_mode == 0x01)
		{
			SF_mode = 0x32; //ECB DES
		}
	else if(SF_mode == 0x02)
		{
			SF_mode = 0x33; //CBC DES
		}
	else if(SF_mode == 0x40)
		{
			SF_mode = 0x30; //ECB 3DES
		}
	else if(SF_mode == 0x80)
		{
			SF_mode = 0x31; //CBC 3DES
		}

	hex_asc(data, temp, datalen);
	sprintf(
			csLog,
			"SUNSON_DataCompute, KeyId = %d,JM_mode, = %02x,SF_mode = %02x,padchar = %02x,datalen = %d",
			KeyId, JM_mode, SF_mode, padchar, datalen);
	g_Log.WriteLog(csLog);
	*DataResult = 0x00;
	if(g_bLogClearSecret == false)
	{
		sprintf(csLog,"data = %s",temp);
		g_Log.WriteLog(csLog);
	}

	unsigned char *CommandData=new unsigned char[datalen+15];
	memset(CommandData,0,datalen+15);
	int nReturnValue=-1;
	CommandData[0]=0x1b;
	CommandData[1]=0x44;
	CommandData[2]=0x4f;
	CommandData[3]=(datalen+8)/256;
	CommandData[4]=(datalen+8)%256;
	CommandData[5]=KeyId/256;
	CommandData[6]=KeyId%256;
	CommandData[7]=JM_mode;
	CommandData[8]=SF_mode;
	CommandData[9]=padchar;
	CommandData[10]=datalen/256;
	CommandData[11]=datalen%256;
	for(int i=0;i<datalen;i++)
		CommandData[12+i]=data[i];
	int templen=12+datalen;
	for(i=0;i<templen;i++)
		CommandData[templen]^=CommandData[i];	
	CommandData[13+datalen]=0x0d;
	CommandData[14+datalen]=0x0a;
	i = sendUsbData(CommandData, 15 + datalen,2000);
	if (i == 0)
	{
		int nRetlen = 0;
		nReturnValue = recvData(DataResult, &nRetlen, 6000);
		nReturnValue = nRetlen;
		if (nReturnValue > 0)
		{
			unsigned char temp[5000] =
			{ 0 };
			hex_asc(DataResult, temp, nReturnValue);
			if(g_bLogClearSecret == false)
				sprintf(csLog, "SUNSON_DataCompute, DataResult = %s", temp);
			else
				strcpy(csLog, "SUNSON_DataCompute success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			unsigned char ResultInfo[2] =
			{ 0 };
			hex_asc_char(DataResult[0], ResultInfo);
			sprintf(csLog, "SUNSON_DataCompute, ReturnInfo = 0x%c%c(失败)",
					ResultInfo[0], ResultInfo[1]);
			g_Log.WriteLog(csLog);
		}
		delete[] CommandData;
		CommandData = NULL;
		g_mutex.Unlock(); 
		return nReturnValue;
	}
	else
	{
		sprintf(csLog, "SUNSON_DataCompute, ReturnInfo = 0x%02x(失败)",
				DataResult[0]);
		g_Log.WriteLog(csLog);
		delete[] CommandData;
		CommandData = NULL;
		g_mutex.Unlock(); 
		return 0;
	}
}

//B.11取PIN操作
int SUNSON_GetPin(unsigned char ucPinMinLen, unsigned char ucPinMaxLen,
		unsigned char AutoReturnFlag, unsigned char *ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialGetPin(ucPinMinLen, ucPinMaxLen, AutoReturnFlag, ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---取PIN操作---");
	char csLog[1024] =
	{ 0 };
	sprintf(
			csLog,
			"SUNSON_GetPin, PinMinLen = %d,PinMaxLen, = %d,AutoReturnFlag = %02x",
			ucPinMinLen, ucPinMaxLen, AutoReturnFlag);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	int i = 0;
	int nReturnValue = -1;
	unsigned char CommandData[12] =
	{ 0x1b, 0x52, 0x50, 0x00, 0x05, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x0d, 0x0a };
	//if (ucPinMaxLen == 0 || ucPinMaxLen > 12)
	//	ucPinMaxLen = 12;
	CommandData[5] = ucPinMinLen;
	CommandData[6] = ucPinMaxLen;
	CommandData[7] = AutoReturnFlag;
	for (i = 0; i < 9; i++)
		CommandData[9] ^= CommandData[i];
	i = sendUsbData(CommandData, 12,1000);
	if (i == 0)
	{
		int nLen = 0;
		nReturnValue = recv_ST(ReturnInfo, &nLen, 1000);
		if (nReturnValue == 0)
		{
			g_Log.WriteLog("SUNSON_GetPin,success!");
		}
		else
		{
			sprintf(csLog, "SUNSON_GetPin,failure! errorinfo = 0x%02x",
					ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		g_mutex.Unlock(); 
		return nLen;
	}
	sprintf(csLog, "SUNSON_GetPin,failure! errorinfo = 0x%02x", ReturnInfo[0]);
	g_Log.WriteLog(csLog);
	g_mutex.Unlock(); 
	return 0;
}

//B.12Pinblock运算
/*
 JM_mode
 */
int SUNSON_GetPinBlock(int UserKeyId, int JM_mode, unsigned char padchar,
		unsigned char CardLen, unsigned char*CardNo,
		unsigned char*PinBlockResult)
{
	if(g_IsCom)
	{
		return SUNSON_SerialGetPinBlock(UserKeyId, JM_mode, padchar, CardLen, CardNo, PinBlockResult);
	}
g_mutex.Lock();
	int i = 0;
	g_Log.WriteLog("---Pinblock运算---");
	char csLog[1024] =
	{ 0 };
	char temp[1024] =
	{ 0 };
	memcpy(temp, CardNo, CardLen);
	sprintf(
			csLog,
			"SUNSON_GetPinBlock, UserKeyId = %d,JM_mode, = %02x,padchar = %02x,CardLen = %d",
			UserKeyId, JM_mode, padchar, CardLen);
	g_Log.WriteLog(csLog);
	*PinBlockResult = 0x00;
	if(g_bLogClearSecret == false)
	{
		g_Log.WriteLog((char*)CardNo);
	}

	//兼容F35的调用，JM_mode如果传递F35的参数，则做个转换
	if(JM_mode == 0x01)
		{
			JM_mode = 0x34;// IBM3624格式
		}
	else if(JM_mode == 0x02)
		{
			JM_mode = 0X35;// X9.8格式
		}
	else if(JM_mode == 0x04)
		{
			JM_mode = 0x30;// ISO9564格式0 
		}	
	else if(JM_mode == 0x08)
		{
			JM_mode = 0x31;// ISO9564格式1
		}

	if(JM_mode==0x34 ) //IS0格式1,IBM3624
	{
		//if(JM_mode==0x31 || JM_mode==0x34)
		{
			CardLen=12;
			for(int m=0;m<12;m++)
				CardNo[m]=0x00;
		}
	}
	if(JM_mode==0x31)
	{
		if(CardLen>10)
			CardLen=10;
	}

	if(JM_mode==0x30 || JM_mode==0x31||JM_mode==0x33|| JM_mode==0x35)
	{
		if(CardLen!=0)
		{
			if(strlen((char*)CardNo)==0)
			{
				for(int n=0;n<CardLen;n++)
					CardNo[n]=0x00;
			}
		}
	}

	int nCardRealLen = CardLen;
	unsigned char CommandData[26];
	memset(CommandData, 0, 26);
	int nReturnValue = -1;
	CommandData[0] = 0x1b;
	CommandData[1] = 0x50;
	CommandData[2] = 0x42;
	CommandData[3] = 0x00;
	CommandData[4] = 6 + nCardRealLen;
	CommandData[5] = UserKeyId / 256;
	CommandData[6] = UserKeyId % 256;
	CommandData[7] = JM_mode;
	CommandData[8]=padchar,
	CommandData[9] = CardLen;
	for (int i = 0; i < nCardRealLen; i++)
		CommandData[10 + i] = CardNo[i];
	int templen = 10 + nCardRealLen;
	for (i = 0; i < templen; i++)
		CommandData[templen] ^= CommandData[i];
	CommandData[11 + nCardRealLen] = 0x0d;
	CommandData[12 + nCardRealLen] = 0x0a;
	i = sendUsbData(CommandData, 13 + nCardRealLen,2000);
	if (i == 0)
	{
		int nRetlen = 0;
		nReturnValue = recvData(PinBlockResult, &nRetlen, 2000);
		nReturnValue = nRetlen;
		if (nReturnValue > 0)
		{
			unsigned char temp[1024] =
			{ 0 };
			hex_asc(PinBlockResult, temp, nReturnValue);
			if(g_bLogClearSecret == false)
				sprintf(csLog, "SUNSON_GetPinBlock, success ,pinblock=%s",(char*)temp);
			else
				sprintf(csLog, "SUNSON_GetPinBlock, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			unsigned char ResultInfo[2] =
			{ 0 };
			hex_asc_char(PinBlockResult[0], ResultInfo);
			sprintf(csLog, "SUNSON_GetPinBlock, ReturnInfo = 0x%c%c(失败)",
					ResultInfo[0], ResultInfo[1]);
			g_Log.WriteLog(csLog);
		}
		g_mutex.Unlock(); 
		return nReturnValue;
	}
	else
	{
		sprintf(csLog, "SUNSON_GetPinBlock, PinBlockResult = 0x%02x(失败)",
				PinBlockResult[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}

int MakeMac(int UserKeyId,int Mac_mode,int nMacDataLen,unsigned char *ucMacData,unsigned char *MacResult)
{
	char csLog[20000] = {0};
	sprintf(csLog,"MakeMac, UserKeyId = %d,Mac_mode = %02x,nMacDataLen = %d,",UserKeyId,Mac_mode,nMacDataLen);
	g_Log.WriteLog(csLog);

	if(g_bLogClearSecret == false)
	{
		unsigned char temp[12000] = {0};
		hex_asc(ucMacData,temp,nMacDataLen);
		sprintf(csLog,"MacDataBlock= %s",temp);
		g_Log.WriteLog(csLog);
	}
	*MacResult = 0x00;

	int i=0;
	unsigned char CommandData[10000];
	memset(CommandData,0,10000);
	int nReturnValue=-1;
	CommandData[0]=0x1b;
	CommandData[1]=0x4d;
	CommandData[2]=0x43;
	CommandData[3]=(nMacDataLen+6)/256;
	CommandData[4]=(nMacDataLen+6)%256;
	CommandData[5]=UserKeyId/256;
	CommandData[6]=UserKeyId%256;	
	CommandData[7]=Mac_mode;
	CommandData[8]=nMacDataLen/256;
	CommandData[9]=nMacDataLen%256;
	for(int i=0;i<nMacDataLen;i++)
		CommandData[10+i]=ucMacData[i];
	int templen=10+nMacDataLen;
	for(int i=0;i<templen;i++)
		CommandData[templen]^=CommandData[i];
	CommandData[11+nMacDataLen]=0x0d;
	CommandData[12+nMacDataLen]=0x0a;

	//DWORD t1 = GetTickCount();
	i=sendUsbData(CommandData, 13 + nMacDataLen,2000);
	if(i==0)
	{
		//DWORD t2 = GetTickCount();
		//sprintf(csLog,"USB_ExeCommand =%d",t2-t1);
		//g_Log.WriteLog(csLog);
		int nRetlen = 0;
		nReturnValue = recvData(MacResult, &nRetlen, 5000);
		nReturnValue = nRetlen;
		if (nReturnValue>0)
		{
			if(g_bLogClearSecret == false)
			{
				unsigned char temp[1024] = {0};
				hex_asc(MacResult,temp,nReturnValue);
				sprintf(csLog,"MakeMac, result = %s",temp);
				g_Log.WriteLog(csLog);
			}
		}
		else
		{
			//unsigned char ResultInfo[2] = {0};
			//ASCII_Hex(MacResult[0],ResultInfo);
			sprintf(csLog,"MakeMac, ReturnInfo = 0x%02X(失败)",MacResult[0]);
			g_Log.WriteLog(csLog);
		}

		return nReturnValue;				
	}
	else
	{
		sprintf(csLog,"MakeMac, send error ReturnInfo = 0x%02x(失败)",MacResult[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}

//B.13MAC运算
/*
 Mac_mode
 #define WFS_PIN_CRYPTDESMAC    (0x0020)
 #define WFS_PIN_CRYPTTRIDESMAC (0x0200)
 */
int SUNSON_MakeMac(int UserKeyId, int Mac_mode, int nMacDataLen,
		unsigned char *ucMacData, unsigned char *MacResult)
{
	if(g_IsCom)
	{
		return SUNSON_SerialMakeMac(UserKeyId, Mac_mode, nMacDataLen, ucMacData, MacResult);
	}
g_mutex.Lock();
	//int i = 0;
	g_Log.WriteLog("---MAC运算---");
	if(Mac_mode == 0x20)
		{
			Mac_mode = 0x30; //X9.9
		}
	else if(Mac_mode == 0x21)
		{
			Mac_mode = 0x35; //X9.9T
		}
	else if(Mac_mode == 0x32)
		{
			Mac_mode = 0x32; //UBC
		}	
	else if(Mac_mode == 0x200)
		{
			Mac_mode = 0x33; //X9.19
		}
	*MacResult = 0x00;
	if(g_bLogClearSecret == false)
	{
		//sprintf(csLog,"MacData = %s",tempdata);
		//g_Log.WriteLog(csLog);
	}

	if(nMacDataLen <= g_MacBlockNum)
	{
		int ret = MakeMac(UserKeyId, Mac_mode, nMacDataLen, ucMacData, MacResult);
		g_mutex.Unlock(); 
		return ret;
	}

	int nDataLine = ((nMacDataLen)%g_MacBlockNum == 0)?((nMacDataLen)/g_MacBlockNum):((nMacDataLen)/g_MacBlockNum + 1); //Mac数据分组

	int nItemLen = 0;
	unsigned char ActiveMacMode = 0x00;
	unsigned char ucMacResult[17];
	unsigned char MacData[6000] = {0};
	int nflag = 0;
	for (int m=0;m<nDataLine;m++)
	{
		memset(ucMacResult,0,17);
		int nlen = (m == (nDataLine - 1))?(nMacDataLen- g_MacBlockNum*m):g_MacBlockNum; //计算每组计算的长度

		if (m != 0)  //不是第一组时要与后面8字节进行异或
		{
			for(int i=0;i<nItemLen;i++)
			{
				ucMacData[i +m*g_MacBlockNum]^=MacData[i];
			}
		}
		for (int i=0; i<nlen; i++)
		{
			MacData[i] = ucMacData[i +m*g_MacBlockNum];
		}

		if(Mac_mode == 0x35) //MAA
			ActiveMacMode = 0x35;
		else
			ActiveMacMode = 0x30;

		// 最后一组用原始mode
		if(m==nDataLine-1)
			ActiveMacMode = Mac_mode;

		nflag = MakeMac(UserKeyId,ActiveMacMode,nlen,MacData,ucMacResult); //拆分的全部用X9.9算法，在最后一步处理
		if(nflag > 0)
		{
			nItemLen = nflag;
			memcpy(MacData,ucMacResult,nItemLen);
		}
		else
		{
			g_mutex.Unlock(); 
			return 0; //运算失败	
		}
	}
	memcpy(MacResult,ucMacResult,nflag);
	g_mutex.Unlock(); 
	return nflag;
	
	/*
	unsigned char CommandData[2061];
	memset(CommandData, 0, 2061);
	int nReturnValue = -1;
	CommandData[0] = 0x1b;
	CommandData[1] = 0x4d;
	CommandData[2] = 0x43;
	CommandData[3] = (nMacDataLen + 6) / 256;
	CommandData[4] = (nMacDataLen + 6) % 256;
	CommandData[5] = UserKeyId / 256;
	CommandData[6] = UserKeyId % 256;
	CommandData[7] = Mac_mode;
	CommandData[8] = nMacDataLen / 256;
	CommandData[9] = nMacDataLen % 256;
	for (int i = 0; i < nMacDataLen; i++)
		CommandData[10 + i] = ucMacData[i];
	int templen = 10 + nMacDataLen;
	for (i = 0; i < templen; i++)
		CommandData[templen] ^= CommandData[i];
	CommandData[11 + nMacDataLen] = 0x0d;
	CommandData[12 + nMacDataLen] = 0x0a;
	i = sendUsbData(CommandData, 13 + nMacDataLen,2000);
	if (i == 0)
	{
		int nRetlen = 0;
		nReturnValue = recvData(MacResult, &nRetlen, 2000);
		nReturnValue = nRetlen;
		if (nReturnValue > 0)
		{
			unsigned char temp[1024] =
			{ 0 };
			hex_asc(MacResult, temp, nReturnValue);
			if(g_bLogClearSecret == false)
				sprintf(csLog, "SUNSON_MakeMac, DataResult = %s", temp);
			else
				sprintf(csLog, "SUNSON_MakeMac, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			unsigned char ResultInfo[2] =
			{ 0 };
			hex_asc_char(MacResult[0], ResultInfo);
			sprintf(csLog, "SUNSON_MakeMac, ReturnInfo = 0x%c%c(失败)",
					ResultInfo[0], ResultInfo[1]);
			g_Log.WriteLog(csLog);
		}
		return nReturnValue;
	}
	else
	{
		sprintf(csLog, "SUNSON_MakeMac, ReturnInfo = 0x%02x(失败)", MacResult[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}*/
}

//B.14使用EPP仿真键盘
int SUNSON_UseEppPlainTextMode(unsigned char PlaintextLength,
							   unsigned char AutoEnd, unsigned char *ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialUseEppPlainTextMode(PlaintextLength, AutoEnd, ReturnInfo);
	}
g_mutex.Lock();
	int i = 0;
	g_Log.WriteLog("---使用EPP仿真键盘---");
	char csLog[1024] =
	{ 0 };
	sprintf(csLog,
		"SUNSON_UseEppPlainTextMode, PlaintextLength = %d,AutoEnd = %02x",
		PlaintextLength, AutoEnd);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	int nReturnValue = -1;
	unsigned char CommandData[10] =
	{ 0x1b, 'O', 'K', 0x00, 0x03, 0x00, 0x00, 0x00, 0x0d, 0x0a };
	CommandData[5] = PlaintextLength;
	CommandData[6] = AutoEnd;
	for (i = 0; i < 7; i++)
		CommandData[7] ^= CommandData[i];
	i = sendUsbData(CommandData, 10,1000);
	if (i == 0)
	{
		int nLen = 0;
		nReturnValue = recv_ST(ReturnInfo, &nLen, 1000);
		if (nReturnValue == 0)
		{
			g_Log.WriteLog("SUNSON_UseEppPlainTextMode,success!");
		}
		else
		{
			sprintf(csLog,
				"SUNSON_UseEppPlainTextMode,failure! errorinfo = 0x%02x",
				ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		g_mutex.Unlock(); 
		return nLen;
	}
	else
	{
		sprintf(csLog,
			"SUNSON_UseEppPlainTextMode,failure! errorinfo = 0x%02x",
			ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}

//B.15关闭EPP仿真键盘
int SUNSON_CloseEppPlainTextMode(unsigned char *ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialCloseEppPlainTextMode(ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---使用EPP仿真键盘---");
	g_Log.WriteLog("SUNSON_CloseEppPlainTextMode");
	char csLog[1024] =
	{ 0 };
	*ReturnInfo = 0x00;

	int nReturnValue = -1;
	unsigned char CommandData[8] =
	{ 0x1b, 'C', 'K', 0x00, 0x01, 0x12, 0x0d, 0x0a };
	int i = sendUsbData(CommandData, 8,1000);
	if (i == 0)
	{
		int nLen = 0;
		nReturnValue = recv_ST(ReturnInfo, &nLen, 1000);
		if (nReturnValue == 0)
		{
			g_Log.WriteLog("SUNSON_CloseEppPlainTextMode,success!");
		}
		else
		{
			sprintf(csLog,
					"SUNSON_CloseEppPlainTextMode,failure! errorinfo = 0x%02x",
					ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		g_mutex.Unlock(); 
		return nLen;
	}
	else
	{
		sprintf(csLog,
				"SUNSON_CloseEppPlainTextMode,failure! errorinfo = 0x%02x",
				ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}

}

//B.16  取随机数,成功返回指定随机数长度，失败返回0
int SUNSON_GetRandomData(unsigned char ucRandomDataType,
		unsigned char ucDataLength, unsigned char *ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialGetRandomData(ucRandomDataType, ucDataLength, ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---取随机数---");
	char csLog[1024] =
	{ 0 };
	sprintf(csLog,
			"SUNSON_GetRandomData, ucRandomDataType = %02x,ucDataLength = %d",
			ucRandomDataType, ucDataLength);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	int i = 0;
	int nReturnValue = -1;
	unsigned char CommandData[10] =
	{ 0x1b, 0x52, 0x41, 0x00, 0x03, 0x30, 0x00, 0x00, 0x0d, 0x0a };
	CommandData[5] = ucRandomDataType;
	CommandData[6] = ucDataLength;
	for (i = 0; i < 7; i++)
		CommandData[7] ^= CommandData[i];
	i = sendUsbData(CommandData, 10,1000);
	if (i == 0)
	{
		int nRetlen = 0;
		nReturnValue = recvData(ReturnInfo, &nRetlen, 2000);
		nReturnValue = nRetlen;
		if (nReturnValue > 0)
		{
			unsigned char temp[1024] =
			{ 0 };
			hex_asc(ReturnInfo, temp, nReturnValue);
			if(g_bLogClearSecret == false)
				sprintf(csLog, "SUNSON_GetRandomData, DataResult = %s", temp);
			else
				sprintf(csLog, "SUNSON_GetRandomData, success");
			
			g_Log.WriteLog(csLog);
		}
		else
		{
			unsigned char ResultInfo[2] =
			{ 0 };
			hex_asc_char(ReturnInfo[0], ResultInfo);
			sprintf(csLog, "SUNSON_GetRandomData, ReturnInfo = 0x%c%c(失败)",
					ResultInfo[0], ResultInfo[1]);
			g_Log.WriteLog(csLog);
		}
		g_mutex.Unlock(); 
		return nReturnValue;
	}
	else
	{
		sprintf(csLog, "SUNSON_GetRandomData, ReturnInfo = 0x%02x(失败)",
				ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}

//2012-6-15  add by xiaweiqian
//山东浪潮增加此算法
//UBC mac  支持2K数据   macdata 传ASCII字符串
int SUNSON_MakeUBCMac(int UserKeyId,int nMacLen,unsigned char* macdata,unsigned char *ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialMakeUBCMac(UserKeyId, nMacLen, macdata, ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---UBC算法mac---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_MakeUBCMac, nMacLen = %d,UserKeyId = %d",nMacLen,UserKeyId);
	g_Log.WriteLog(csLog);

	int nDataLine=0; //Mac数据长度
	if (nMacLen%8==0)
	{
		nDataLine=nMacLen/8;
	}
	else
	{
		nDataLine=(nMacLen/8+1);
	}

	int nRealMacDataLen=nDataLine*8;
	unsigned char *ucRealMacData = new unsigned char[nRealMacDataLen];
	memset(ucRealMacData,0,nRealMacDataLen);//Mac数据填充

	for (int m=0;m<nMacLen;m++)
	{
		ucRealMacData[m] = macdata[m];
	}

	unsigned char ucXorData[8];
	memset(ucXorData,0,8);
	int i=-1;
	//8字节Mac数据，无需异或
	if (nDataLine==1)
	{
		for (i=0;i<8;i++)
		{
			ucXorData[i]=ucRealMacData[i];
		}
	}
	else 
		if (nDataLine>=2) //Mac数据长度大于16字节
		{
			for (i=0;i<8;i++) //先将前16字节依次异或
			{
				ucXorData[i]=ucRealMacData[i]^ucRealMacData[i+8];
			}

			if (nDataLine>2) //将前16个字节的异或值与后续的每8个字节做异或
			{
				for(int k=2;k<nDataLine;k++)
				{
					for(i=0;i<8;i++)
						ucXorData[i]^=ucRealMacData[i+k*8];

				}		
			}
		}
		//将异或值按ASCII拆分，1位变两位
		unsigned char ucHexMacData[16];
		memset(ucHexMacData,0,16);
		hex_asc(ucXorData,ucHexMacData,8);

		unsigned char ucQianHexData[8]; //异或值前八个字节
		memset(ucQianHexData,0,8);
		unsigned char ucHouHexData[8];  //异或值后八个字节
		memset(ucHouHexData,0,8);

		for (i=0;i<8;i++)
		{
			ucQianHexData[i]=ucHexMacData[i];
			ucHouHexData[i]=ucHexMacData[i+8];
		}

		unsigned char ucFirstData[16];  //前八字节数据做ＤＥＳ运算结果
		memset(ucFirstData,0,16);

		unsigned char nEncryDataLen=8;
		int nEncryDataResult = SUNSON_MakeMac(UserKeyId,0x30,nEncryDataLen,ucQianHexData,ucFirstData);


		unsigned char ucFirstXorData[8]; // 存储前8字节加密结果与后八字节异或运算的结果
		memset(ucFirstXorData,0,8);
		if (nEncryDataResult >=0)
		{
			for (i=0;i<8;i++)
			{
				ucFirstXorData[i]=ucFirstData[i]^ucHouHexData[i];
			}
		}
		else
		{
			delete[] ucRealMacData;
			ucRealMacData=NULL;
			g_mutex.Unlock(); 
			return CMD_FAILS;
		}

		unsigned char ucSecondData[16];  //异或结果做DES运算
		memset(ucSecondData,0,16);	

		nEncryDataResult=SUNSON_MakeMac(UserKeyId,0x30,nEncryDataLen,ucFirstXorData,ucSecondData);
		if (nEncryDataResult>=0)
		{
			unsigned char tempResult[40] = {0};
			unsigned char tempResult1[60] = {0};

			for (i=0;i<8;i++)
			{

				tempResult[i]=ucSecondData[i]; //存储最后的mac结果
			}

			hex_asc(tempResult,tempResult1,8);

			for(i=0; i<8; i++)
			{
				ReturnInfo[i] = tempResult1[i];
			}

			if(g_bLogClearSecret == false)
			{
				g_Log.WriteLog("UBC运算结果：");
				sprintf(csLog,"%s",ReturnInfo);
			}
			else
				sprintf(csLog,"UBC mac success");	
			g_Log.WriteLog(csLog);

			delete[] ucRealMacData;
			ucRealMacData=NULL;

			g_mutex.Unlock(); 
			return nEncryDataResult;
		}
		delete[] ucRealMacData;
		ucRealMacData=NULL;
		g_mutex.Unlock(); 
		return 0;
}

//获取键盘状态  add 20131103 nby,获取初始化状态添加
int SUNSON_GetEppStatus(unsigned char*EppStatus)
{
	if(g_IsCom)
	{
		return SUNSON_SerialGetEppStatus(EppStatus);
	}
g_mutex.Lock();
	g_Log.WriteLog("---取EPP状态---");
	g_Log.WriteLog("SUNSON_GetEppStatus");
	char csLog[1024] = {0};
	*EppStatus = 0x00;

	int i=0;
	int nReturnValue=-1;
	unsigned char CommandData[8]={0x1b,0x45,0x57,0x00,0x01,0x00,0x0d,0x0a};
	CommandData[5]=CommandData[0]^CommandData[1]^CommandData[2]^CommandData[3]^CommandData[4];

	i=sendUsbData(CommandData,8,1000);
	if(i==0)
	{
		int nRetlen = 0;
		nReturnValue=recvData(EppStatus, &nRetlen, 2000);
		nReturnValue = nRetlen;
		if (nReturnValue>0)
		{
			unsigned char temp[1024] = {0};
			hex_asc(EppStatus,temp,nReturnValue);
			sprintf(csLog,"SUNSON_GetEppStatus, DataResult = %s",temp);
			g_Log.WriteLog(csLog);
		}
		else
		{
			unsigned char ResultInfo[2] = {0};
			hex_asc_char(EppStatus[0],ResultInfo);
			sprintf(csLog,"SUNSON_GetEppStatus, ReturnInfo = 0x%c%c(失败)",ResultInfo[0],ResultInfo[1]);
			g_Log.WriteLog(csLog);
		}
		g_mutex.Unlock(); 
		return nReturnValue;		
	}
	else 
	{
		sprintf(csLog,"SUNSON_GetEppStatus, ReturnInfo = 0x%02x(失败)",EppStatus[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}

//设定卡键时间命令
int SUNSON_SetLockKeyTimeOut(unsigned char TimeOut,unsigned char *ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialSetLockKeyTimeOut(TimeOut, ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---设置卡键时间---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SetLockKeyTimeOut,TimeOut= %d",TimeOut);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	int i=0;
	int nReturnValue=-1;
	unsigned char CommandData[10]={0x1b,0x53,0x4A,0x00,0x02,0x00,0x00,0x0d,0x0a};
	CommandData[5]=TimeOut;
	CommandData[6]=CommandData[0]^CommandData[1]^CommandData[2]^CommandData[3]^CommandData[4]^CommandData[5];

	i=sendUsbData(CommandData,9,1000);
	if(i==0)
	{
		int nLen = 0;
		nReturnValue=recv_ST(ReturnInfo, &nLen, 1000);
		if (nReturnValue == 0)
		{
			g_Log.WriteLog("SUNSON_SetLockKeyTimeOut,success!");
		}
		else
		{
			sprintf(csLog,"SUNSON_SetLockKeyTimeOut,failure! errorinfo = 0x%02x",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		g_mutex.Unlock(); 
		return nLen;
	}
	else 
	{
		sprintf(csLog,"SUNSON_SetLockKeyTimeOut,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}

//打开/关闭开封自毁   0x00 关闭固件自毁(仅100N支持)
//                    0x01 开启固件自毁(仅100N支持)
//                    0x02 关闭密钥自毁
//                    0x04 开启密钥自毁
int SUNSON_EnableMoveDestruct(unsigned char mode, unsigned char *ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialEnableMoveDestruct(mode, ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("****设置开封自毁****");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_EnableMoveDestruct,ucSMMode = 0x%02X",mode);
	g_Log.WriteLog(csLog);
	int i = -1;
	int ST = -1;
	unsigned char command[32] = {0};
	command[0] = 0x1b;
	command[1] = 0x54;
	command[2] = 0x32;
	command[3] = 0x00;
	command[4] = 0x02;
	command[5] = mode;

	for(i=0;i<6;i++)
		command[6]^=command[i];

	command[7] = 0x0d;
	command[8] = 0x0a;

	i = sendUsbData(command,9,1000);
	if(0 == i)
	{
		int nLen = 0;
		ST = recv_ST(ReturnInfo, &nLen, 1000); 
		if (0 == ST)
		{
			g_Log.WriteLog("打开自毁设置成功！");
		}
		else
			g_Log.WriteLog("打开自毁设置失败！");
		g_mutex.Unlock(); 
		return nLen;
	}
	else
	{
		g_mutex.Unlock(); 
		return 0;
	}
}

//设置国密非国密模式
int SUNSON_SetEPPSMMode(unsigned char ucSMMode)
{
	if(g_IsCom)
	{
		return SUNSON_SerialSetEPPSMMode(ucSMMode);
	}

	g_Log.WriteLog("****设置国密非国密模式****");
g_mutex.Lock();
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SetEPPSMMode,ucSMMode = 0x%02X",ucSMMode);
	g_Log.WriteLog(csLog);
	int i = -1;
	int ST = -1;
	unsigned char ReturnInfo[32] = {0};
	unsigned char command[32] = {0};
	command[0] = 0x1b;
	command[1] = 0x53;
	command[2] = 0x57;
	command[3] = 0x00;
	command[4] = 0x02;
	command[5] = ucSMMode;

	for(i=0;i<6;i++)
		command[6]^=command[i];

	command[7] = 0x0d;
	command[8] = 0x0a;
	i = sendUsbData(command,9,1000);
	if(0 == i)
	{
		int nLen = 0;
		ST = recv_ST(ReturnInfo, &nLen, 1000);
		if (0 == ST)
		{
			switch (ucSMMode)
			{
			case  0x00: //非国密模式
				g_bSMmode = false;
				g_Log.WriteLog("非国密模式设置成功！");
				break;
			case 0x01: //国密模式
				g_bSMmode = true;
				g_Log.WriteLog("国密模式设置成功！");
				break;
			default:break;
			}
			g_mutex.Unlock(); 
			return nLen;
		}
		else
			g_Log.WriteLog("国密模式设置失败！");

		g_mutex.Unlock(); 
		return 0;
	}
	else
	{
		g_mutex.Unlock(); 
		return 0;
	}
}

//获取键盘模式 国密 非国密
int SUNSON_GetEPPSMMode(unsigned char *ucEPPMode)
{
	if(g_IsCom)
	{
		return SUNSON_SerialGetEPPSMMode(ucEPPMode);
	}
g_mutex.Lock();
	g_Log.WriteLog("****获取键盘模式****");
	char csLog[1024] = {0};
	int i = -1;
	int ST = -1;
	unsigned char command[32] = {0};
	command[0] = 0x1b;
	command[1] = 0x47;
	command[2] = 0x57;
	command[3] = 0x00;
	command[4] = 0x02;
	command[5] = 0x91;

	for(i=0;i<6;i++)
		command[6]^=command[i];

	command[7] = 0x0d;
	command[8] = 0x0a;
	i = sendUsbData(command,9,1000);
	if(0 == i)
	{
		int nLen = 0;
		ST = recv_ST(ucEPPMode, &nLen, 1000);
		sprintf(csLog,"SUNSON_GetEPPMode,ucEPPMode = %02X",ucEPPMode[0]);
		g_Log.WriteLog(csLog);
		if(ST == 0)
		{
			if(ucEPPMode[0] == 0x00)
			{
				g_bSMmode = false;
			}
			else if(ucEPPMode[0] == 0x01)
			{
				g_bSMmode = true;
			}
			g_Log.WriteLog("获取键盘模式成功！");
			g_mutex.Unlock(); 
			return nLen;
		}
		else
			g_Log.WriteLog("获取键盘模式失败！");

		g_mutex.Unlock(); 
		return 0;
	}
	else
	{
		g_mutex.Unlock(); 
		return 0;
	}
}
//生成SM2密钥
int SUNSON_GenerateSM2Key(int ucKeyId,int KeyAtt,unsigned char *ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialGenerateSM2Key(ucKeyId, KeyAtt, ReturnInfo);
	}
g_mutex.Lock();
	KeyAtt = 0x0F;
	g_Log.WriteLog("---生成SM2密钥---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_GenerateSM2Key, ucKeyId = %d, keyAttr=0x%02X",ucKeyId, KeyAtt);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;
	int i=0;
	int nReturnValue=-1;

	unsigned char CommandData[255] = {0};
	CommandData[0] = 0x1b;
	CommandData[1] = 0x47;
	CommandData[2] = 0x4d;
	CommandData[3] = 0x00;
	CommandData[4] = 0x04;
	CommandData[5] = ucKeyId/256;
	CommandData[6] = ucKeyId%256;
	CommandData[7] = KeyAtt;

	for(i=0; i<8; i++)
		CommandData[8]^=CommandData[i];

	CommandData[9]=0x0d;
	CommandData[10]=0x0a;
	i = sendUsbData(CommandData,11,1000);
	if(i==0)
	{
		int nLen = 0;
		nReturnValue=recv_ST(ReturnInfo, &nLen, 2000);
		if (nReturnValue ==0)
		{
			g_Log.WriteLog("SUNSON_GenerateSM2Key,success!");
		}
		else
		{
			sprintf(csLog,"SUNSON_GenerateSM2Key,failure! errorinfo = 0x%x",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		g_mutex.Unlock(); 
		return nLen;
	}
	else
	{
		sprintf(csLog,"SUNSON_GenerateSM2Key,failure! errorinfo = 0x%x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}

//下载SM2密钥
int SUNSON_LoadSM2Key(int ucKeyId,int KeyAtt,int nKeylen,unsigned char *KeyValue,unsigned char *ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialLoadSM2Key(ucKeyId, KeyAtt, nKeylen, KeyValue, ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---下载SM2密钥---");
	char csLog[1024] = {0};
	unsigned char HexKeyData[1024] = {0};
	hex_asc(KeyValue,HexKeyData,nKeylen);
	sprintf(csLog,"SUNSON_LoadSM2Key,ucKeyId = %02x,KeyAtt = %02x,nKeylen = %d",ucKeyId,KeyAtt,nKeylen);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;
	if(g_bLogClearSecret == false)
	{
		sprintf(csLog,"HexKeyData = %s",HexKeyData);
		g_Log.WriteLog(csLog);		
	}

	int i=0;
	int nReturnValue=-1;
	unsigned char CommandData[255];
	memset(CommandData,0,255);
	unsigned char data[4];
	memset(data,0,4);
	CommandData[0] = 0x1b;
	CommandData[1] = 0x4c;
	CommandData[2] = 0x53;
	CommandData[3] = (5+nKeylen)/256;
	CommandData[4] = (5+nKeylen)%256;
	CommandData[5] = nKeylen;
	CommandData[6] = ucKeyId/256;
	CommandData[7] = ucKeyId%256;
	CommandData[8] = KeyAtt;

	for(i=0;i<nKeylen;i++)
	{
		CommandData[9+i]=KeyValue[i];
	}

	for(i=0;i< (9+nKeylen) ;i++)
		CommandData[9+nKeylen]^=CommandData[i];

	CommandData[10+nKeylen] = 0x0d;
	CommandData[11+nKeylen] = 0x0a;

	i=sendUsbData(CommandData,12+nKeylen,2000);
	if(i==0)
	{
		int nLen = 0;
		nReturnValue=recv_ST(ReturnInfo, &nLen, 1000);
		if (nReturnValue ==0)
		{
			g_Log.WriteLog("SUNSON_LoadSM2Key,success!");
		}
		else
		{
			sprintf(csLog,"SUNSON_LoadSM2Key,failure! errorinfo = 0x%02x",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		g_mutex.Unlock(); 
		return nLen;
	}
	else
	{
		sprintf(csLog,"SUNSON_LoadSM2Key,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}

//导出SM2公钥
int SUNSON_ExportSM2PublicKey(int ucKeyId,unsigned char *SM2PKeyValue)
{
	if(g_IsCom)
	{
		return SUNSON_SerialExportSM2PublicKey(ucKeyId, SM2PKeyValue);
	}
g_mutex.Lock();
	g_Log.WriteLog("---导出SM2公钥---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_ExportSM2PublicKey, ucKeyId = %d",ucKeyId);
	g_Log.WriteLog(csLog);
	*SM2PKeyValue = 0x00;
	int i=0;
	int nReturnValue=-1;
	unsigned char CommandData[255] = {0};
	CommandData[0] = 0x1b;
	CommandData[1] = 0x45;
	CommandData[2] = 0x4d;
	CommandData[3] = 0x00;
	CommandData[4] = 0x04;
	CommandData[5] = ucKeyId/256;
	CommandData[6] = ucKeyId%256;
	CommandData[7] = 0x50;

	for(i=0; i<8; i++)
		CommandData[8]^=CommandData[i];

	CommandData[9]=0x0d;
	CommandData[10]=0x0a;

	i = sendUsbData(CommandData,11,1000);
	if(0 == i)
	{
		int nRetlen = 0;
		nReturnValue = recvData(SM2PKeyValue, &nRetlen, 2000);
		nReturnValue = nRetlen;
		if (nReturnValue > 0)
		{
			unsigned char temp[1024] = {0};
			hex_asc(SM2PKeyValue,temp,nReturnValue);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_ExportSM2PublicKey, keyValue = %s",temp);
			else
				sprintf(csLog,"SUNSON_ExportSM2PublicKey, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			unsigned char ResultInfo[2] = {0};
			hex_asc_char(SM2PKeyValue[0],ResultInfo);
			sprintf(csLog,"SUNSON_ExportSM2PublicKey, ReturnInfo = 0x%c%c(失败)",ResultInfo[0],ResultInfo[1]);
			g_Log.WriteLog(csLog);
		}
		g_mutex.Unlock(); 
		return nReturnValue;
	}
	else
	{
		sprintf(csLog,"SUNSON_ExportSM2PublicKey, ReturnInfo = 0x%02x(失败)",SM2PKeyValue[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}

//Hash ID初始化
int SUNSON_InitHashID(int ucKeyId,unsigned char UserIDLen,unsigned char *UserID,unsigned char *ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialInitHashID(ucKeyId, UserIDLen, UserID, ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---Hash ID初始化---");
	char csLog[1024] = {0};
	unsigned char HexUserID[1024] = {0};
	hex_asc(UserID,HexUserID,UserIDLen);
	sprintf(csLog,"SUNSON_InitHashID, ucKeyId = %d,UserIDLen = %d, userId=0x%s",ucKeyId,UserIDLen,(char*)HexUserID);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;
	if(g_bLogClearSecret == false)
	{
		sprintf(csLog,"HexUserID = %s",HexUserID);
		g_Log.WriteLog(csLog);
	}

	int i=0;
	int nReturnValue=-1;
	unsigned char *CommandData=new unsigned char[UserIDLen+255];
	memset(CommandData,0,UserIDLen+255);
	CommandData[0] = 0x1b;
	CommandData[1] = 0x47;
	CommandData[2] = 0x49;
	CommandData[3] = (UserIDLen+4)/256;
	CommandData[4] = (UserIDLen+4)%256;
	CommandData[5] = ucKeyId/256;
	CommandData[6] = ucKeyId%256;
	CommandData[7] = UserIDLen;

	for (i = 0; i < UserIDLen; i++)
	{
		CommandData[8+i] = UserID[i];
	}

	for(i=0; i < (8+UserIDLen); i++)
		CommandData[8+UserIDLen]^=CommandData[i];

	CommandData[9 + UserIDLen ]=0x0d;
	CommandData[10 + UserIDLen]=0x0a;

	i = sendUsbData(CommandData,11 +UserIDLen,2000);
	if(0 == i)
	{
		int nRetlen = 0;
		nReturnValue = recvData(ReturnInfo, &nRetlen, 2000);
		nReturnValue = nRetlen;
		if (nReturnValue > 0)
		{
			//unsigned char temp[1024] = {0};
			//hex_asc(ReturnInfo,temp,nReturnValue);
			sprintf(csLog,"SUNSON_InitHashID, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			//unsigned char ResultInfo[2] = {0};
			//hex_asc_char(ReturnInfo[0],ResultInfo);
			sprintf(csLog,"SUNSON_InitHashID, ReturnInfo = 0x%02x(失败)",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		delete [] CommandData;
		CommandData=NULL;
		g_mutex.Unlock(); 
		return nReturnValue;
	}
	else
	{
		sprintf(csLog,"SUNSON_InitHashID, ReturnInfo = 0x%02x(失败)",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		delete [] CommandData;
		CommandData=NULL;
		g_mutex.Unlock(); 
		return 0;
	}
}

//SM2签名
int SUNSON_GetSM2SignatureEX(int ucKeyId,unsigned char EDataLen,unsigned char *EData,unsigned char *ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialGetSM2SignatureEX(ucKeyId, EDataLen, EData, ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---获取SM2签名---");
	char csLog[1024] = {0};
	unsigned char HexEData[1024] = {0};
	hex_asc(EData,HexEData,EDataLen);
	sprintf(csLog,"SUNSON_GetSM2SignatureEX, ucKeyId = %d,EDataLen = %d",ucKeyId,EDataLen);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;
	if(g_bLogClearSecret == false)
	{
		sprintf(csLog,"HexEData = %s",HexEData);
		g_Log.WriteLog(csLog);
	}

	int i=0;
	int nReturnValue=-1;

	unsigned char *CommandData=new unsigned char[EDataLen+255];
	memset(CommandData,0,EDataLen+255);
	CommandData[0] = 0x1b;
	CommandData[1] = 0x47;
	CommandData[2] = 0x51;
	CommandData[3] = (EDataLen+4)/256;
	CommandData[4] = (EDataLen+4)%256;
	CommandData[5] = ucKeyId/256;
	CommandData[6] = ucKeyId%256;
	CommandData[7] = EDataLen;

	for (i = 0; i < EDataLen; i++)
	{
		CommandData[8+i] = EData[i];
	}

	for(i=0; i < (8+EDataLen); i++)
		CommandData[8+EDataLen]^=CommandData[i];

	CommandData[9 + EDataLen]=0x0d;
	CommandData[10 + EDataLen]=0x0a;

	i = sendUsbData(CommandData,11 +EDataLen,2000);
	if(0 == i)
	{
		int nRetlen = 0;
		nReturnValue = recvData(ReturnInfo, &nRetlen, 2000);
		nReturnValue = nRetlen;
		if (nReturnValue > 0)
		{
			unsigned char temp[1024] = {0};
			hex_asc(ReturnInfo,temp,nReturnValue);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_GetSM2SignatureEX, ReturnInfo = %s",temp);
			else
				sprintf(csLog,"SUNSON_GetSM2SignatureEX, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			unsigned char ResultInfo[2] = {0};
			hex_asc_char(ReturnInfo[0],ResultInfo);
			sprintf(csLog,"SUNSON_GetSM2SignatureEX, ReturnInfo = 0x%c%c(失败)",ResultInfo[0],ResultInfo[1]);
			g_Log.WriteLog(csLog);
		}
		delete [] CommandData;
		CommandData=NULL;
		g_mutex.Unlock(); 
		return nReturnValue;
	}
	else
	{
		sprintf(csLog,"SUNSON_GetSM2SignatureEX, ReturnInfo = 0x%02x(失败)",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		delete [] CommandData;
		CommandData=NULL;
		g_mutex.Unlock(); 
		return 0;
	}
}

////1.39 SM2签名,兼容F35接口，OpenFlag忽略
int SUNSON_GetSM2Signature(int ucKeyId,unsigned char OpenFlag,
		int EDataLen,unsigned char *EData,unsigned char *ReturnInfo)
{
	char csLog[2048] = {0};
	unsigned char HexEData[1024] = {0};
	hex_asc(EData,HexEData,EDataLen);
	sprintf(csLog,"SUNSON_GetSM2SignatureF35, ucKeyId = %d,EDataLen = %d,EData = %s",ucKeyId,EDataLen, (char*)HexEData);
	g_Log.WriteLog(csLog);
	
	//初始化userid
	SUNSON_InitHashID(ucKeyId, EData[0], EData+1, ReturnInfo);
	//SM3计算E值
	unsigned char ucResult[256]={0};
	int nlen = SUNSON_SM3HashOperateEX(0x06, EDataLen-EData[0]-1, EData+1+EData[0], ucResult);
	return SUNSON_GetSM2SignatureEX(ucKeyId, nlen, ucResult, ReturnInfo);
}

//SM2验签
int SUNSON_VerifySM2SignatureEX(int ucKeyId,unsigned char EDataLen,unsigned char *EData,unsigned char SignatureLen,unsigned char *Signature,unsigned char *ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialVerifySM2SignatureEX(ucKeyId, EDataLen, EData, SignatureLen, Signature, ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---SM2签名验证---");
	char csLog[1024] = {0};
	unsigned char HexEData[1024] = {0};
	hex_asc(EData,HexEData,EDataLen);
	unsigned char HexSignature[1024] = {0};
	hex_asc(Signature,HexSignature,SignatureLen);
	sprintf(csLog,"SUNSON_VerifySM2SignatureEX, ucKeyId = %d,EDataLen = %d,SignatureLen = %d",ucKeyId,EDataLen,SignatureLen);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	if(g_bLogClearSecret == false)
	{
		sprintf(csLog,"Edata=%s, HexSignature = %s",HexEData, HexSignature);
		g_Log.WriteLog(csLog);
	}

	int i=0;
	int nReturnValue=-1;

	unsigned char *CommandData=new unsigned char[EDataLen+SignatureLen+255];
	memset(CommandData,0,EDataLen+SignatureLen+255);

	CommandData[0] = 0x1b;
	CommandData[1] = 0x47;
	CommandData[2] = 0x56;
	CommandData[3] = (EDataLen+SignatureLen+4)/256;
	CommandData[4] = (EDataLen+SignatureLen+4)%256;
	CommandData[5] = ucKeyId/256;
	CommandData[6] = ucKeyId%256;
	CommandData[7] = EDataLen+SignatureLen;


	for (i = 0; i < SignatureLen; i++)
	{
		CommandData[8+i] = Signature[i];
	}

	for (i = 0; i < EDataLen; i++)
	{
		CommandData[8+SignatureLen+i] = EData[i];
	}

	for(i=0; i < (8+EDataLen+SignatureLen); i++)
		CommandData[8+EDataLen+SignatureLen]^=CommandData[i];

	CommandData[9 + EDataLen+SignatureLen ]=0x0d;
	CommandData[10 + EDataLen+SignatureLen]=0x0a;

	i = sendUsbData(CommandData,11 +EDataLen+SignatureLen,2000);
	if(0 == i)
	{
		int nRetlen = 0;
		nReturnValue = recvData(ReturnInfo, &nRetlen, 2000);
		nReturnValue = nRetlen;
		if (nReturnValue > 0)
		{
			//unsigned char temp[1024] = {0};
			//hex_asc(ReturnInfo,temp,nReturnValue);
			sprintf(csLog,"SUNSON_VerifySM2SignatureEX, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			//unsigned char ResultInfo[2] = {0};
			//hex_asc_char(ReturnInfo[0],ResultInfo);
			sprintf(csLog,"SUNSON_VerifySM2SignatureEX, ReturnInfo = 0x%02x(失败)",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		delete [] CommandData;
		CommandData=NULL;
		g_mutex.Unlock(); 
		return nReturnValue;
	}
	else
	{
		sprintf(csLog,"SUNSON_VerifySM2SignatureEX, ReturnInfo = 0x%02x(失败)",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		delete [] CommandData;
		CommandData=NULL;
		g_mutex.Unlock(); 
		return 0;
	}
}

////1.40 SM2验签,兼容F35接口，OpenFlag忽略
int SUNSON_VerifySM2Signature(int ucKeyId,unsigned char OpenFlag,int SignatureLen,
		unsigned char *Signature,int EDataLen,unsigned char *EData,unsigned char *ReturnInfo)
{
	char csLog[2048] = {0};
	unsigned char HexEData[1024] = {0};
	hex_asc(EData,HexEData,EDataLen);
	sprintf(csLog,"SUNSON_VerifySM2SignatureF35, ucKeyId = %d,EDataLen = %d,EData = %s",ucKeyId,EDataLen, (char*)HexEData);
	g_Log.WriteLog(csLog);
	//初始化userid
	SUNSON_InitHashID(ucKeyId, EData[0], EData+1, ReturnInfo);
	//SM3计算E值
	unsigned char ucResult[256]={0};
	int nlen = SUNSON_SM3HashOperateEX(0x06, EDataLen-EData[0]-1, EData+1+EData[0], ucResult);
	return SUNSON_VerifySM2SignatureEX(ucKeyId, nlen, ucResult, SignatureLen, Signature, ReturnInfo);
}

//SM2数据运算
int SUNSON_SM2DataCompute(int ucKeyId,unsigned char ucKeyType,int nDatalen,unsigned char *data,unsigned char *DataResult)
{
	if(g_IsCom)
	{
		return SUNSON_SerialSM2DataCompute(ucKeyId, ucKeyType, nDatalen, data, DataResult);
	}
g_mutex.Lock();
	g_Log.WriteLog("---SM2数据运算---");
	char csLog[5120] = {0};
	sprintf(csLog,"SUNSON_SM2DataCompute, ucKeyId = %d,ucKeyType, = %02x,nDatalen = %d",ucKeyId,ucKeyType,nDatalen);
	g_Log.WriteLog(csLog);
	*DataResult = 0x00;

	if(g_bLogClearSecret == false)
	{
		unsigned char HexEData[2048] = {0};
		hex_asc(data,HexEData,nDatalen);
		sprintf(csLog,"data = %s",HexEData);
		g_Log.WriteLog(csLog);
	}

	unsigned char *CommandData=new unsigned char[nDatalen+255];
	memset(CommandData,0,nDatalen+255);

	int i = 0;
	int nReturnValue=-1;
	CommandData[0] = 0x1b;
	CommandData[1] = 0x44;
	CommandData[2] = 0x4c;
	CommandData[3] = (nDatalen+5)/256;
	CommandData[4] = (nDatalen+5)%256;
	CommandData[5] = ucKeyType;
	CommandData[6] = ucKeyId/256;
	CommandData[7] = ucKeyId%256;
	CommandData[8] = nDatalen;

	for(i=0; i<nDatalen; i++)
		CommandData[9+i] = data[i];

	int templen = 9+nDatalen;
	for(i=0;i<templen;i++)
		CommandData[templen]^=CommandData[i];

	CommandData[10+nDatalen] = 0x0d;
	CommandData[11+nDatalen] = 0x0a;

	i=sendUsbData(CommandData,12+nDatalen,2000);
	if(i==0)
	{
		int nRetlen = 0;
		nReturnValue=recvData(DataResult, &nRetlen, 3000, 1);
		nReturnValue = nRetlen;
		if (nReturnValue>0)
		{
			unsigned char temp[5120] = {0};
			hex_asc(DataResult,temp,nReturnValue);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_SM2DataCompute, DataResult = %s",temp);
			else
				sprintf(csLog,"SUNSON_SM2DataCompute, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			unsigned char ResultInfo[2] = {0};
			hex_asc_char(DataResult[0],ResultInfo);
			sprintf(csLog,"SUNSON_SM2DataCompute, ReturnInfo = 0x%c%c(失败)",ResultInfo[0],ResultInfo[1]);
			g_Log.WriteLog(csLog);
		}
		delete [] CommandData;
		CommandData=NULL;
		g_mutex.Unlock(); 
		return nReturnValue;
	}
	else
	{
		sprintf(csLog,"SUNSON_SM2DataCompute, ReturnInfo = 0x%02x(失败)",DataResult[0]);
		g_Log.WriteLog(csLog);
		delete [] CommandData;
		CommandData=NULL;
		g_mutex.Unlock(); 
		return 0;
	}
}

//SM3哈希操作
int SUNSON_SM3HashOperateEX(unsigned char ucSM3HashType,int nDatalen,unsigned char *data,unsigned char *DataResult)
{
	if(g_IsCom)
	{
		return SUNSON_SerialSM3HashOperateEX(ucSM3HashType, nDatalen, data, DataResult);
	}
g_mutex.Lock();
	g_Log.WriteLog("---SM3哈希操作---");
	unsigned char HexData[1024] = {0};
	hex_asc(data,HexData,nDatalen);
	char csLog[2048] = {0};
	sprintf(csLog,"SUNSON_SM3HashOperateEX,ucKeyType = %02x,nDatalen = %d",ucSM3HashType,nDatalen);
	g_Log.WriteLog(csLog);
	*DataResult = 0x00;
	if(g_bLogClearSecret == false)
	{
		sprintf(csLog,"data = %s",HexData);
		g_Log.WriteLog(csLog);
	}	

	unsigned char *CommandData=new unsigned char[nDatalen+255];
	memset(CommandData,0,nDatalen+255);

	int i=0;
	int nReturnValue=-1;
	CommandData[0] = 0x1b;
	CommandData[1] = 0x44;
	CommandData[2] = 0x46;
	CommandData[3] = (nDatalen+4)/256;
	CommandData[4] = (nDatalen+4)%256;
	CommandData[5] = ucSM3HashType;
	CommandData[6] = nDatalen/256;
	CommandData[7] = nDatalen%256;

	for(i=0; i<nDatalen; i++)
		CommandData[8+i] = data[i];

	int templen = 8+nDatalen;
	for(i=0;i<templen;i++)
		CommandData[templen]^=CommandData[i];

	CommandData[9+nDatalen] = 0x0d;
	CommandData[10+nDatalen] = 0x0a;

	i=sendUsbData(CommandData,11+nDatalen,2000);
	if(i==0)
	{
		int nRetlen = 0;
		nReturnValue=recvData(DataResult, &nRetlen, 2000);
		nReturnValue = nRetlen;
		if (nReturnValue>0)
		{
			unsigned char temp[2048] = {0};
			hex_asc(DataResult,temp,nReturnValue);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_SM3HashOperateEX, DataResult = %s",temp);
			else
				sprintf(csLog,"SUNSON_SM3HashOperateEX, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			unsigned char ResultInfo[2] = {0};
			hex_asc_char(DataResult[0],ResultInfo);
			sprintf(csLog,"SUNSON_SM3HashOperateEX, ReturnInfo = 0x%c%c(失败)",ResultInfo[0],ResultInfo[1]);
			g_Log.WriteLog(csLog);
		}
		delete [] CommandData;
		CommandData=NULL;
		g_mutex.Unlock(); 
		return nReturnValue;
	}
	else
	{
		sprintf(csLog,"SUNSON_SM3HashOperateEX, ReturnInfo = 0x%02x(失败)",DataResult[0]);
		g_Log.WriteLog(csLog);
		delete [] CommandData;
		CommandData=NULL;
		g_mutex.Unlock(); 
		return 0;
	}
}

//1.42 SM3哈希操作,兼容F35接口，ucSM3HashType忽略
int SUNSON_SM3HashOperate(unsigned char ucSM3HashType,unsigned char OperateFlag,
		int nDatalen,unsigned char *data,unsigned char *DataResult)
{
	return SUNSON_SM3HashOperateEX(OperateFlag, nDatalen, data, DataResult);
}

//使能国密程序下载
int SUNSON_EnableLoadSMFirmware(void)
{
	if(g_IsCom)
	{
		return SUNSON_SerialEnableLoadSMFirmware();
	}
	int i = -1;
	int ST = -1;
	unsigned char ReturnInfo[64] = {0};
	unsigned char command[8] = {0x1B,0x47,0x44,0x00,0x01,0x00,0x0d,0x0a};
	command[5] = command[0]^command[1]^command[2]^command[3]^command[4];

	g_Log.WriteLog("****使用国密程序下载****");

	i = sendUsbData(command,8,1000);
	if(0 == i)
	{
		int nLen = 0;
		ST = recv_ST(ReturnInfo, &nLen, 1000);
		if (0 == ST)
		{
			g_Log.WriteLog("使用国密程序下载成功！");
		}
		else
		{
			g_Log.WriteLog("使用国密程序下载失败！");
		}
		return nLen;
	}
	else
		return 0;
}



//导入SM4密钥，通过SM2解密
int SUNSON_ImportSM4KeyUseSM2key(int nSM2keyID, int nSM4keyID, int nKeyAttr, int nKeyLen, unsigned char* KeyValue, unsigned char* ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialImportSM4KeyUseSM2key(nSM2keyID, nSM4keyID, nKeyAttr, nKeyLen, KeyValue, ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---下载SM4密钥使用SM2解密---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_ImportSM4KeyUseSM2key,nSM2keyID = %02x,nSM4keyID = %02x,KeyAtt = %02x,keyValueLength = %d",nSM2keyID,nSM4keyID,nKeyAttr,nKeyLen);
	g_Log.WriteLog(csLog);
	unsigned char temptxt[512]={0};
	hex_asc(KeyValue, temptxt, nKeyLen);
	if(g_bLogClearSecret == false)
		g_Log.WriteLog((char*)temptxt);
	*ReturnInfo = 0x00;

	int i=0;
	//int len=0;
	int nReturnValue=-1;
	unsigned char CommandData[1024];
	memset(CommandData,0,1024);
	CommandData[0]=0x1b;
	CommandData[1]=0x5A;
	CommandData[2]=0x41;
	CommandData[3]=0x00;
	CommandData[4]=9+nKeyLen;
	CommandData[5]=nSM4keyID/256;
	CommandData[6]=nSM4keyID%256;
	CommandData[7]=nSM2keyID/256;
	CommandData[8]=nSM2keyID%256;
	CommandData[12]=nKeyAttr;
	
	for(i=0;i<nKeyLen;i++)
	{
		CommandData[13+i]=KeyValue[i];
	}

	for(i=0;i<13+nKeyLen;i++)
		CommandData[13+nKeyLen]^=CommandData[i];
	CommandData[14+nKeyLen]=0x0d;
	CommandData[15+nKeyLen]=0x0a;

	i=sendUsbData(CommandData,16+nKeyLen,1000);
	if(i==0)
	{
		int nRetlen = 0;
		nReturnValue=recvData(ReturnInfo, &nRetlen, 2000);
		nReturnValue = nRetlen;
		if (nReturnValue > 0)
		{
			unsigned char temp[1024] = {0};
			hex_asc(ReturnInfo,temp,nReturnValue);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_ImportSM4KeyUseSM2key, Value = %s",temp);
			else 
				sprintf(csLog,"SUNSON_ImportSM4KeyUseSM2key,success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			sprintf(csLog,"SUNSON_ImportSM4KeyUseSM2key,failure! errorinfo = 0x%02x",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		g_mutex.Unlock(); 
		return nReturnValue;	
	}
	else
	{
		sprintf(csLog,"SUNSON_ImportSM4KeyUseSM2key,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}

//设置能否重复下载密钥 00 允许重复下载； 01 不允许重复下载
int SUNSON_EnableLoadSameKey(unsigned char Mode, unsigned char *ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialEnableLoadSameKey(Mode, ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("****设置密钥重复下载****");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_EnableLoadSameKey,ucSMMode = 0x%02X",Mode);
	g_Log.WriteLog(csLog);
	int i = -1;
	int ST = -1;
	unsigned char command[32] = {0};
	command[0] = 0x1b;
	command[1] = 0x4b;
	command[2] = 0x52;
	command[3] = 0x00;
	command[4] = 0x02;
	command[5] = Mode;

	for(i=0;i<6;i++)
		command[6]^=command[i];

	command[7] = 0x0d;
	command[8] = 0x0a;

	i = sendUsbData(command,9,1000);
	if(0 == i)
	{
		int nLen = 0;
		ST = recv_ST(ReturnInfo, &nLen, 1000);
		if (0 == ST)
		{
			g_Log.WriteLog("设置密钥重复下载模式成功！");
		}
		else
			g_Log.WriteLog("设置密钥重复下载模式失败！");

		g_mutex.Unlock(); 
		return nLen;
	}
	else
	{
		g_mutex.Unlock(); 
		return 0;
	}
}

//获取指定密钥的KCV
int SUNSON_GetKCV(int keyId, unsigned char ucCheckMode,unsigned char *CheckValue)
{
	if(g_IsCom)
	{
		return SUNSON_SerialGetKCV(keyId, ucCheckMode, CheckValue);
	}
g_mutex.Lock();
	g_Log.WriteLog("****获取指定密钥的KCV****");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_GetKCV,keyId=0x%02X, ucMode = 0x%02X", keyId, ucCheckMode);
	g_Log.WriteLog(csLog);
	int i = -1;
	int ST = -1;
	short mode=0;
	mode = ucCheckMode + (((short)keyId)<<4);
	*CheckValue = 0x00;

	unsigned char ucMode[3] = {0};
	ucMode[0] = (char)(mode>>8);
	ucMode[1] = (char)mode;

	unsigned char command[32] = {0};
	command[0] = 0x1b;
	command[1] = 0x54;
	command[2] = 0x31;
	command[3] = 0x00;
	command[4] = 0x03;
	command[5] = ucMode[0];
	command[6] = ucMode[1];

	for(i=0;i<7;i++)
		command[7]^=command[i];

	command[8] = 0x0d;
	command[9] = 0x0a;

	i = sendUsbData(command,10,1000);
	if(0 == i)
	{
		int nRetlen = 0;
		ST=recvData(CheckValue, &nRetlen, 2000);
		ST = nRetlen;
		if (ST>0)
		{
			unsigned char temp[1024] = {0};
			hex_asc(CheckValue,temp,ST);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_GetKCV, CheckValue = %s",temp);
			else
				sprintf(csLog,"SUNSON_GetKCV, success");
	
			g_Log.WriteLog(csLog);
		}
		else
		{
			unsigned char ResultInfo[2] = {0};
			hex_asc_char(CheckValue[0],ResultInfo);
			sprintf(csLog,"SUNSON_GetKCV, ReturnInfo = 0x%c%c(失败)",ResultInfo[0],ResultInfo[1]);
			g_Log.WriteLog(csLog);
		}
		g_mutex.Unlock(); 
		return ST;
	}
	else
	{
		g_mutex.Unlock(); 
		return 0;
	}
}

//获取密钥属性值
int SUNSON_GetKeyAttInfo(int UserKeyId,unsigned char *KeyAttInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialGetKeyAttInfo(UserKeyId, KeyAttInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---获取密钥属性---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_GetKeyAttInfo,UserKeyId = %02x",UserKeyId);
	g_Log.WriteLog(csLog);
	*KeyAttInfo = 0x00;

	int i=0;
	int nReturnValue=-1;
	unsigned char CommandData[10]={0x1b,0x45,0x53,0x00,0x03,0x00,0x00,0x00,0x0d,0x0a};
	CommandData[5]=UserKeyId/256;
	CommandData[6]=UserKeyId%256;
	for(i=0;i<7;i++)
		CommandData[7]^=CommandData[i];
	i=sendUsbData(CommandData,10,1000);
	if(i==0)
	{
		int nRetlen = 0;
		nReturnValue=recvData(KeyAttInfo, &nRetlen, 2000);
		nReturnValue = nRetlen;
		if (nReturnValue>0)
		{
			unsigned char temp[1024] = {0};
			hex_asc(KeyAttInfo,temp,nReturnValue);
			sprintf(csLog,"SUNSON_GetKeyAttInfo, DataResult = %s",temp);
			g_Log.WriteLog(csLog);
		}
		else
		{
			unsigned char ResultInfo[2] = {0};
			hex_asc_char(KeyAttInfo[0],ResultInfo);
			sprintf(csLog,"SUNSON_GetKeyAttInfo, ReturnInfo = 0x%c%c(失败)",ResultInfo[0],ResultInfo[1]);
			g_Log.WriteLog(csLog);
		}
		g_mutex.Unlock(); 
		return nReturnValue;
	}
	else
	{
		sprintf(csLog,"SUNSON_GetKeyAttInfo, ReturnInfo = 0x%02x(失败)",KeyAttInfo[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}

//设置波特率 mode 0x30 2400:
//  0x31 4800:
//  0x32 9600
//  0x33 19200
//  0x34 38400
//  0x35 57600
//  0x36 115200
int SUNSON_SetBaudRate(unsigned char ucBaudRateMode,unsigned char *ReturnInfo)
{	
	if(g_IsCom)
	{
		return SUNSON_SerialSetBaudRate(ucBaudRateMode, ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---设置波特率---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SetBaudRate,ucBaudRateMode = %d",ucBaudRateMode);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	int nReturnValue=-1;
	unsigned char CommandData[9]={0x1b,0x53,0x42,0x00,0x02,0x00,0x00,0x0d,0x0a};	
	CommandData[5]=ucBaudRateMode;
	for(int i=0;i<6;i++)
		CommandData[6]^=CommandData[i];
	
	int i=sendUsbData(CommandData,9,1000);
	if(i==0)
	{
		int nLen = 0;
		nReturnValue=recv_ST(ReturnInfo, &nLen, 1000);
		if (nReturnValue ==0)
		{
			g_Log.WriteLog("SUNSON_SetBaudRate,success!");
		}
		else
		{
			sprintf(csLog,"SUNSON_SetBaudRate,failure! errorinfo1 = 0x%02x",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		g_mutex.Unlock(); 
		return nLen;		
	}
	else
	{
		sprintf(csLog,"SUNSON_SetBaudRate,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}

//开关usb明文系统键盘
//                      0x01   关闭系统键盘
//                      0x02   开启系统键盘              
int SUNSON_EnableUSBplaintext(unsigned char mode)
{
	if(g_IsCom)
	{
		return SUNSON_SerialEnableUSBplaintext(mode);
	}
g_mutex.Lock();
	g_Log.WriteLog("---使能系统键盘功能---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_EnableUSBplaintext,mode = %d",mode);
	g_Log.WriteLog(csLog);

	unsigned char ReturnInfo[256] = {0};

	int i=0;
	int nReturnValue=-1;
	unsigned char CommandData[10]={0x1b,0x54,0x4d,0x00,0x02,mode,0x00,0x0d,0x0a};
	for(i=0;i<6;i++)
		CommandData[6]^=CommandData[i];

	i=sendUsbData(CommandData,9,1000);
	if(i==0)
	{
		int nLen = 0;
		nReturnValue=recv_ST(ReturnInfo, &nLen, 1000);
		if (nReturnValue==0)
		{
			sprintf(csLog,"SUNSON_EnableUSBplaintext, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			sprintf(csLog,"SUNSON_EnableUSBplaintext, ReturnInfo = 0x%02x(失败)",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
			g_mutex.Unlock(); 
			return 0;
		}
		g_mutex.Unlock(); 
		return nLen;	
	}
	else 
	{
		sprintf(csLog,"SUNSON_EnableUSBplaintext, failed");
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
	g_mutex.Unlock(); 
	return 0;
}

//开关日志  0-关闭日志；1-打开日志
void SUNSON_OpenLog(int nFlag)
{
	// if(nFlag == 0)
	// 	bLogLevel = false;
	// else if(nFlag == 1)
	// 	bLogLevel = true;	
}

//开关日志，设置日志级别
//bFlag, 0关闭日志，1 打开日志
//nLogLevel, 0不带敏感信息（卡号、pinblock数据）；1-带敏感数据
void SUNSON_OpenLogEx(unsigned char bFlag, int nLogLevel)
{
	SUNSON_OpenLog(bFlag);
	if(nLogLevel == 0)
		g_bLogClearSecret = true;
	else
		g_bLogClearSecret = false;
}

//导出RSA密钥
int SUNSON_ExportRSAKey(unsigned char ucKeyId, unsigned char *ucData)
{
	if(g_IsCom)
	{
		return SUNSON_SerialExportRSAKey(ucKeyId, ucData);
	}
g_mutex.Lock();
	g_Log.WriteLog("---导出RSA密钥---");
	char csLog[4096] = {0};
	sprintf(csLog,"SUNSON_ExportRSAKey, KeyID = %d",ucKeyId);
	g_Log.WriteLog(csLog);

	int i=0;
	int ST=-1;
	unsigned char CommandData[10] = {0x1b,0x45,0x50,0x00,0x02,ucKeyId, 0x00,0x0D,0x0A};
	for (i = 0 ; i < 6 ; i++)
	{
		CommandData[6] ^= CommandData[i];
	}

	i=sendUsbData(CommandData,9,1000);
	if(i==0)
	{
		int nRetlen = 0;
		ST=recvData(ucData, &nRetlen, 2000);
		ST = nRetlen;
		if (ST>0)
		{
			unsigned char temp[4096] = {0};
			hex_asc(ucData,temp,ST);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_ExportRSAKey, ucData = %s",temp);
			else
				sprintf(csLog,"SUNSON_ExportRSAKey, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			sprintf(csLog,"SUNSON_ExportRSAKey, ReturnInfo = 0x%02x(失败)",ucData[0]);
			g_Log.WriteLog(csLog);
			g_mutex.Unlock(); 
			return 0;
		}
		g_mutex.Unlock(); 
		return ST;
	}
	else
	{
		sprintf(csLog,"SUNSON_ExportRSAKey,failure! errorinfo = 0x%02x",ucData[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}
//下载RSA密钥（部分键盘支持）
int SUNSON_LoadRSAKey(unsigned char ucKeyId,unsigned char nSignatureId, int nKeylen, unsigned char *KeyValue, int nSignatureLen, unsigned char* SignatureData, unsigned char * ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialLoadRSAKey(ucKeyId, nSignatureId, nKeylen, KeyValue, nSignatureLen, SignatureData, ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---下载RSA密钥---");
	char csLog[2048] = {0};
	sprintf(csLog,"SUNSON_LoadRSAKey,KeyId = %02x,signatureId = %02x,keyLength = %d, signatureLen=%d",ucKeyId,nSignatureId,nKeylen,nSignatureLen);
	g_Log.WriteLog(csLog);

	unsigned char temp[1024] = {0};
	unsigned char temp2[1024] = {0};
	hex_asc(KeyValue,temp,nKeylen);
	hex_asc(SignatureData,temp2,nSignatureLen);

	if(g_bLogClearSecret == false)
	{
		sprintf(csLog,"keyvalue=%s, signdata=%s",temp,temp2);
		g_Log.WriteLog(csLog);
	}

	int i=0, nReturnValue = 0;
	unsigned char CommandData[4096] = {0};
	CommandData[0] = 0x1B;
	CommandData[1] = 0x4C;
	CommandData[2] = 0x52;
	CommandData[3] = (nKeylen + nSignatureLen + 7)/256;
	CommandData[4] = (nKeylen + nSignatureLen + 7)%256;
	CommandData[5] = ucKeyId;
	CommandData[6] = nSignatureId;
	CommandData[7] = (nKeylen >> 8) & 0xFF;
	CommandData[8] = nKeylen & 0xFF;
	memcpy(&CommandData[9], KeyValue, nKeylen);
	CommandData[nKeylen+9] = (nSignatureLen >>8) & 0xFF;
	CommandData[nKeylen+10] = nSignatureLen & 0xFF;
	memcpy(&CommandData[nKeylen+11], SignatureData, nSignatureLen);
	for (i = 0; i < nKeylen+nSignatureLen+11; i++)
	{
		CommandData[nKeylen+nSignatureLen+11] ^=  CommandData[i];
	}
	CommandData[nKeylen+nSignatureLen+12] = 0x0D;
	CommandData[nKeylen+nSignatureLen+13] = 0x0A;

	i=sendUsbData(CommandData,14+nKeylen+nSignatureLen,2000);
	if(i==0)
	{
		int nLen = 0;
		nReturnValue=recv_ST(ReturnInfo, &nLen, 1000);
		if (nReturnValue ==0)
		{
			g_Log.WriteLog("SUNSON_LoadRSAKey,success!");
		}
		else
		{
			sprintf(csLog,"SUNSON_LoadRSAKey,failure! errorinfo1 = 0x%02x",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
			g_mutex.Unlock(); 
			return 0;
		}
		g_mutex.Unlock();
		return nLen;
	}
	else
	{
		sprintf(csLog,"SUNSON_LoadRSAKey,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}

//RSA签名
int SUNSON_GetRSASignature(unsigned char ucKeyId, unsigned char Padding,unsigned char HashId,int DataLen,
											   unsigned char *ucData,unsigned char *DataResult)
{
	if(g_IsCom)
	{
		return SUNSON_SerialGetRSASignature(ucKeyId, Padding, HashId, DataLen, ucData, DataResult);
	}
g_mutex.Lock();
	g_Log.WriteLog("---RSA签名---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_GetRSASignature, KeyID = %d,Padding = %X, HashId = %X",ucKeyId, Padding, HashId);
	g_Log.WriteLog(csLog);
	*DataResult = 0x00;

	int i = 0;
	unsigned char *CommandData=new unsigned char[DataLen+255];
	memset(CommandData,0,DataLen+255);
	CommandData[0] = 0x1B;
	CommandData[1] = 0x52;
	CommandData[2] = 0x47;
	CommandData[3] = ((DataLen + 6)/256) & 0xFF;
	CommandData[4] = ((DataLen + 6)%256) & 0xFF;
	CommandData[5] = ucKeyId;
	CommandData[6] = Padding;
	CommandData[7] = HashId;
	CommandData[8] = (DataLen/256) & 0xFF;
	CommandData[9] = (DataLen%256) & 0xFF;
	memcpy(&CommandData[10], ucData, DataLen);

	for (i = 0; i < DataLen+10; i++)
	{
		CommandData[DataLen+10] ^= CommandData[i];
	}
	CommandData[DataLen+11] = 0x0D;
	CommandData[DataLen+12] = 0x0A;
	i=sendUsbData(CommandData,DataLen+13,2000);
	if(i==0)
	{
		int nRetlen = 0;
		int ReturnLen = recvData(DataResult, &nRetlen, 2000);
		ReturnLen = nRetlen;
		if (ReturnLen>0)
		{
			unsigned char temp[1024] = {0};
			hex_asc(DataResult,temp,ReturnLen);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_GetRSASignature, ucData = %s",temp);
			else
				sprintf(csLog,"SUNSON_GetRSASignature, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			sprintf(csLog,"SUNSON_GetRSASignature, ReturnInfo = 0x%02x(失败)",DataResult[0]);
			g_Log.WriteLog(csLog);
		}
		delete []CommandData;
		CommandData = NULL;

		g_mutex.Unlock(); 
		return ReturnLen;
	}
	else
	{
		sprintf(csLog,"SUNSON_GetRSASignature,failure! errorinfo = 0x%02x",DataResult[0]);
		g_Log.WriteLog(csLog);
		delete []CommandData;
		CommandData = NULL;
		g_mutex.Unlock(); 
		return 0;
	}
}

//RSA验签
int SUNSON_VerifyRSASignature(unsigned char ucKeyId, unsigned char Padding,unsigned char HashId,int SignLen,
												  unsigned char *SignData,int DataLen,unsigned char *ucData,unsigned char *ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialVerifyRSASignature(ucKeyId, Padding, HashId, SignLen, SignData, DataLen, ucData, ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---RSA验签---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_VerifyRSASignature, KeyID = %d,Padding = %X, HashId = %X",ucKeyId, Padding, HashId);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	unsigned char *CommandData=new unsigned char[DataLen+SignLen+255];
	memset(CommandData,0,DataLen+SignLen+255);
	CommandData[0] = 0x1B;
	CommandData[1] = 0x52;
	CommandData[2] = 0x56;
	CommandData[3] = ((DataLen + SignLen + 8)/256) & 0xFF;
	CommandData[4] = ((DataLen + SignLen + 8)%256) & 0xFF;
	CommandData[5] = ucKeyId;
	CommandData[6] = Padding;
	CommandData[7] = HashId;
	CommandData[8] = (SignLen/256) & 0xFF;
	CommandData[9] = (SignLen%256) & 0xFF;
	memcpy(&CommandData[10], SignData, SignLen);
	CommandData[SignLen+10] = (DataLen/256) & 0xFF;
	CommandData[SignLen+11] = (DataLen%256) & 0xFF;
	memcpy(&CommandData[SignLen+12], ucData, DataLen);

	for (int i = 0; i < DataLen+SignLen+12; i++)
	{
		CommandData[DataLen+SignLen+12] ^= CommandData[i];
	}
	CommandData[DataLen+SignLen+13] = 0x0D;
	CommandData[DataLen+SignLen+14] = 0x0A;
	int iRet=sendUsbData(CommandData,DataLen+SignLen+15,2000);
	if(iRet==0)
	{
		int nLen = 0;
		int ReturnLen = recv_ST(ReturnInfo, &nLen, 2000);
		if (ReturnLen ==0)
		{
			g_Log.WriteLog("SUNSON_VerifyRSASignature,success!");
		}
		else
		{
			sprintf(csLog,"SUNSON_VerifyRSASignature,failure! errorinfo1 = 0x%02x",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		delete []CommandData;
		CommandData = NULL;
		g_mutex.Unlock(); 
		return nLen;
	}
	else
	{
		sprintf(csLog,"SUNSON_VerifyRSASignature,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		delete []CommandData;
		CommandData = NULL;
		g_mutex.Unlock(); 
		return 0;
	}
}

//RSA导出签名DER（部分键盘支持）
int SUNSON_ExportRSASignDer(unsigned char ucKeyId, unsigned char SignkeyId, unsigned long SignAlg, unsigned char *ucData)
{
	if(g_IsCom)
	{
		return SUNSON_SerialExportRSASignDer(ucKeyId, SignkeyId, SignAlg, ucData);
	}
g_mutex.Lock();
	g_Log.WriteLog("---RSA导出签名DER---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_ExportRSASignDer, KeyId = %d, SignkeyId = %d",	ucKeyId, SignkeyId);
	g_Log.WriteLog(csLog);
	*ucData = 0x00;
	int i = 0;

	unsigned char ucCommand[14] = {0x1B,0x41,0x53,0x00,0x07,ucKeyId,SignkeyId,0x00,0x00,0x00,0x00,0x00,0x0D,0x0A};
	ucCommand[7] = (SignAlg >> 24) & 0xFF;
	ucCommand[8] = (SignAlg >> 16) & 0xFF;
	ucCommand[9] = (SignAlg >> 8) & 0xFF;
	ucCommand[10] = SignAlg & 0xFF;
	for (i = 0; i < 11; i++)
	{
		ucCommand[11] ^= ucCommand[i];
	}
	i=sendUsbData(ucCommand,14,1000);
	if(i==0)
	{
		int nRetlen = 0;
		int ReturnLen = recvData(ucData, &nRetlen, 2000);
		ReturnLen = nRetlen;
		if (ReturnLen>0)
		{
			unsigned char temp[1024] = {0};
			hex_asc(ucData,temp,ReturnLen);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_ExportRSASignDer, ucData = %s",temp);
			else
				sprintf(csLog,"SUNSON_ExportRSASignDer, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			sprintf(csLog,"SUNSON_ExportRSASignDer, ReturnInfo = 0x%02x(失败)",ucData[0]);
			g_Log.WriteLog(csLog);
		}
		g_mutex.Unlock(); 
		return ReturnLen;
	}
	else
	{
		sprintf(csLog,"SUNSON_ExportRSASignDer,failure! errorinfo = 0x%02x",ucData[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}


//导入无签名的RSAKEY KeyType = 0x01 导DER私钥
//                   KeyType = 0x02 导DER公钥
int SUNSON_ImportNoSignRSAKey(unsigned char ucKeyId, unsigned char KeyType, int DataLen,unsigned char *ucData,unsigned char *ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialImportNoSignRSAKey(ucKeyId, KeyType, DataLen, ucData, ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---导入无签名的RSAKEY---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_ImportNoSignRSAKey, KeyId = %d, KeyType=%d", ucKeyId, KeyType);
	g_Log.WriteLog(csLog);

	unsigned char *CommandData=new unsigned char[DataLen+255];
	memset(CommandData,0,DataLen+255);
	CommandData[0] = 0x1B;
	CommandData[1] = 0x4C;
	CommandData[2] = 0x4E;
	CommandData[3] = (DataLen+5)/256 & 0xFF;
	CommandData[4] = (DataLen+5)%256 & 0xFF;
	CommandData[5] = ucKeyId;
	CommandData[6] = KeyType;
	CommandData[7] = (DataLen/256) & 0xFF;
	CommandData[8] = (DataLen%256) & 0xFF;
	memcpy(&CommandData[9], ucData, DataLen);
	for (int i = 0; i < (DataLen+9); i++)
	{
		CommandData[DataLen+9] ^= CommandData[i];
	}
	CommandData[DataLen+10] = 0x0D;
	CommandData[DataLen+11] = 0x0A;

	//unsigned char ReturnTxt[1024] = {0};
	//int nRetLen = -1;

	int iRet=sendUsbData(CommandData,DataLen+12,2000);
	if(iRet==0)
	{
		int nLen = 0;
		int ReturnLen = recv_ST(ReturnInfo, &nLen, 1000);
		if (ReturnLen ==0)
		{
			g_Log.WriteLog("SUNSON_ImportNoSignRSAKey,success!");
		}
		else
		{
			sprintf(csLog,"SUNSON_ImportNoSignRSAKey,failure! errorinfo1 = 0x%02x",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		delete []CommandData;
		CommandData = NULL;

		g_mutex.Unlock(); 
		return nLen;
	}
	else
	{
		sprintf(csLog,"SUNSON_ImportSignValue,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);

		delete []CommandData;
		CommandData = NULL;
		g_mutex.Unlock(); 
		return 0;
	}
}

//生成RSA密钥 nKeylen 1024,2048 exp 3, 17, 65537
int SUNSON_GenerateRSAKey(unsigned char ucKeyId, long nKeylen,long Eval, long Dwuse, unsigned char* ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialGenerateRSAKey(ucKeyId, nKeylen, Eval, Dwuse, ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---生成RSA密钥---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_GenerateRSAKey, wKeyID = %d,ModuleLen = %ld,Eval = %ld, Dwuse = %ld",ucKeyId,nKeylen,Eval,Dwuse);
	g_Log.WriteLog(csLog);

	//int ExpLen = 4;
	//unsigned char ucExp[4] = {0};

	int i=0;
	int ST=-1;
	//unsigned char ucReturnInfo[1024] = {0};
	unsigned char CommandData[21] ={0x1b,0x47,0x41,0x00,0x0E,ucKeyId,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0D,0x0A};
	CommandData[8] = (nKeylen/256) & 0xFF;
	CommandData[9] = (nKeylen%256) & 0xFF;
	CommandData[10] = (Eval >> 24) & 0xFF;
	CommandData[11] = (Eval >> 16) & 0xFF;
	CommandData[12] = (Eval >> 8) & 0xFF;
	CommandData[13] = Eval & 0xFF;
	CommandData[14] = (Dwuse >> 24) & 0xFF;
	CommandData[15] = (Dwuse >> 16) & 0xFF;
	CommandData[16] = (Dwuse >> 8) & 0xFF;
	CommandData[17] = Dwuse & 0xFF;

	for (i = 0 ; i < 18 ; i++)
	{
		CommandData[18] ^= CommandData[i];
	}

	i=sendUsbData(CommandData,21,1000);
	if(i==0)
	{
		int nRetLen = 0;
		ST=recv_ST(ReturnInfo, &nRetLen, 180000);
		if (ST ==0)
		{
			g_Log.WriteLog("SUNSON_GenerateRSAKey,success!");
		}
		else
		{
			sprintf(csLog,"SUNSON_GenerateRSAKey,failure! errorinfo1 = 0x%02x",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
			g_mutex.Unlock(); 
			return 0;
		}
		g_mutex.Unlock(); 
		return nRetLen;	
	}
	else
	{
		sprintf(csLog,"SUNSON_GenerateRSAKey,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}

//导出RSA DerKey mode:0x01 DER格式, 0x02:256字节N值
int SUNSON_ExportRSADerKey(unsigned char ucKeyId, unsigned char mode, int *nkeyderLen, unsigned char *ucKeyDer, int *nSignLen, unsigned char *ucSignData, unsigned char* ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialExportRSADerKey(ucKeyId, mode, nkeyderLen, ucKeyDer, nSignLen, ucSignData, ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---RSA导出DerKey---");
	char csLog[4096] = {0};
	sprintf(csLog,"SUNSON_ExportRSADerKey, KeyID = %d, mode=%d",ucKeyId, mode);
	g_Log.WriteLog(csLog);
	unsigned char ucData[4096]={0};
	int i = 0;

	int len = 0;
	if(mode == 0) //0的时候不发mode
	{
		unsigned char ucCommand[12] = {0x1B,0x45,0x52,0x00,0x02,ucKeyId,0x00,0x0D,0x0A};
		for (i = 0; i < 6; i++)
		{
			ucCommand[6] ^= ucCommand[i];
		}
		i=sendUsbData(ucCommand,9,1000);
		len = 9;
	}
	else
	{
		unsigned char ucCommand[12] = {0x1B,0x45,0x52,0x00,0x03,ucKeyId,mode,0x00,0x0D,0x0A};
		for (i = 0; i < 7; i++)
		{
			ucCommand[7] ^= ucCommand[i];
		}
		i=sendUsbData(ucCommand,10,1000);
		len = 10;
	}

	if(i==0)
	{
		int nRetlen = 0;
		int ReturnLen = recvData(ucData, &nRetlen, 2000);
		ReturnLen = nRetlen;
		if (ReturnLen>0)
		{
			unsigned char temp[4096] = {0};
			hex_asc(ucData,temp,ReturnLen);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_ExportRSADerKey, ucData = %s",temp);
			else
				sprintf(csLog,"SUNSON_ExportRSADerKey, success");
			*nkeyderLen = (ucData[0]<<8)|ucData[1];
			memcpy(ucKeyDer, ucData+2, *nkeyderLen);
			int nlen = 2+(*nkeyderLen);
			*nSignLen = (ucData[nlen]<<8)|ucData[nlen+1];
			memcpy(ucSignData, ucData+nlen+2, *nSignLen);

			g_Log.WriteLog(csLog);
		}
		else
		{
			ReturnInfo[0]=ucData[0];
			sprintf(csLog,"SUNSON_ExportRSADerKey, ReturnInfo = 0x%02x(失败)",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		g_mutex.Unlock(); 
		return ReturnLen;
	}
	else
	{
		ReturnInfo[0]=ucData[0];
		sprintf(csLog,"SUNSON_ExportRSADerKey,failure! errorinfo = 0x%02x",ucData[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}

//导入RSA DerKey
int SUNSON_ImportRSADerKey(unsigned char ucKeyId, unsigned char SignkeyId, int DerKeyLen, unsigned char *DerKey, long Dwuse, 
											   long SignAlg, long CheckMode, int SignLen, unsigned char *SignDat, unsigned char *ucResult)
{
	if(g_IsCom)
	{
		return SUNSON_SerialImportRSADerKey(ucKeyId, SignkeyId, DerKeyLen, DerKey, Dwuse, SignAlg, CheckMode, SignLen, SignDat, ucResult);
	}
g_mutex.Lock();
	g_Log.WriteLog("---RSA导入DerKey---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_ImportRSADerKey, KeyID = %d,SignkeyId = %X, Dwuse = %ld, SignAlg = %lX, CheckMode = %ld",ucKeyId, SignkeyId, Dwuse, SignAlg, CheckMode);
	g_Log.WriteLog(csLog);
	*ucResult = 0x00;

	unsigned char *CommandData=new unsigned char[DerKeyLen+SignLen+255];
	memset(CommandData,0,DerKeyLen+SignLen+255);
	CommandData[0] = 0x1B;
	CommandData[1] = 0x49;
	CommandData[2] = 0x52;
	CommandData[3] = ((DerKeyLen + SignLen + 19)/256) & 0xFF;
	CommandData[4] = ((DerKeyLen + SignLen + 19)%256) & 0xFF;
	CommandData[5] = ucKeyId;
	CommandData[6] = SignkeyId;
	CommandData[7] = (DerKeyLen/256) & 0xFF;
	CommandData[8] = (DerKeyLen%256) & 0xFF;
	memcpy(&CommandData[9], DerKey, DerKeyLen);
	CommandData[DerKeyLen+9] = (Dwuse >> 24) & 0xFF;
	CommandData[DerKeyLen+10] = (Dwuse >> 16) & 0xFF;
	CommandData[DerKeyLen+11] = (Dwuse >> 8) & 0xFF;
	CommandData[DerKeyLen+12] = Dwuse & 0xFF;
	CommandData[DerKeyLen+13] = (SignAlg >> 24) & 0xFF;
	CommandData[DerKeyLen+14] = (SignAlg >> 16) & 0xFF;
	CommandData[DerKeyLen+15] = (SignAlg >> 8) & 0xFF;
	CommandData[DerKeyLen+16] = SignAlg & 0xFF;
	CommandData[DerKeyLen+17] = (CheckMode >> 24) & 0xFF;
	CommandData[DerKeyLen+18] = (CheckMode >> 16) & 0xFF;
	CommandData[DerKeyLen+19] = (CheckMode >> 8) & 0xFF;
	CommandData[DerKeyLen+20] = CheckMode & 0xFF;
	CommandData[DerKeyLen+21] = (SignLen/256) & 0xFF;
	CommandData[DerKeyLen+22] = (SignLen%256) & 0xFF;
	memcpy(&CommandData[DerKeyLen+23], SignDat, SignLen);
	for (int i = 0; i < DerKeyLen+SignLen+23; i++)
	{
		CommandData[DerKeyLen+SignLen+23] ^= CommandData[i];
	}
	CommandData[DerKeyLen+SignLen+24] = 0x0D;
	CommandData[DerKeyLen+SignLen+25] = 0x0A;
	int iRet=sendUsbData(CommandData,DerKeyLen+SignLen+26,2000);
	if(iRet==0)
	{
		int nRetlen = 0;
		int ReturnLen = recvData(ucResult, &nRetlen, 2000);
		ReturnLen = nRetlen;
		if (ReturnLen>0)
		{
			unsigned char temp[1024] = {0};
			hex_asc(ucResult,temp,ReturnLen);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_ImportRSADerKey, ucData = %s",temp);
			else
				sprintf(csLog,"SUNSON_ImportRSADerKey, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			sprintf(csLog,"SUNSON_ImportRSADerKey, ReturnInfo = 0x%02x(失败)",ucResult[0]);
			g_Log.WriteLog(csLog);
		}
		delete []CommandData;
		CommandData = NULL;

		g_mutex.Unlock(); 
		return ReturnLen;
	}
	else
	{
		sprintf(csLog,"SUNSON_ImportRSADerKey,failure! errorinfo = 0x%02x",ucResult[0]);
		g_Log.WriteLog(csLog);
		delete []CommandData;
		CommandData = NULL;
		g_mutex.Unlock(); 
		return 0;
	}
}

//导入签名值
int SUNSON_ImportSignValue(unsigned char ucKeyId, int SignLen, unsigned char * SignData, unsigned char *ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialImportSignValue(ucKeyId, SignLen, SignData, ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---RSA导入签名值---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_ImportSignValue, KeyId = %d",	ucKeyId);
	g_Log.WriteLog(csLog);

	unsigned char *CommandData=new unsigned char[SignLen+255];
	memset(CommandData,0,SignLen+255);
	CommandData[0] = 0x1B;
	CommandData[1] = 0x52;
	CommandData[2] = 0x4C;
	CommandData[3] = (SignLen+4)/256 & 0xFF;
	CommandData[4] = (SignLen+4)%256 & 0xFF;
	CommandData[5] = ucKeyId;
	CommandData[6] = (SignLen/256) & 0xFF;
	CommandData[7] = (SignLen%256) & 0xFF;
	memcpy(&CommandData[8], SignData, SignLen);
	for (int i = 0; i < (SignLen+8); i++)
	{
		CommandData[SignLen+8] ^= CommandData[i];
	}
	CommandData[SignLen+9] = 0x0D;
	CommandData[SignLen+10] = 0x0A;
	int iRet=sendUsbData(CommandData,SignLen+11,2000);
	if(iRet==0)
	{
		int nLen = 0;
		int ReturnLen = recv_ST(ReturnInfo, &nLen, 1000);
		if (ReturnLen ==0)
		{
			g_Log.WriteLog("SUNSON_ImportSignValue,success!");
		}
		else
		{
			sprintf(csLog,"SUNSON_ImportSignValue,failure! errorinfo = 0x%02x",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		delete []CommandData;
		CommandData = NULL;

		g_mutex.Unlock(); 
		return nLen;
	}
	else
	{
		sprintf(csLog,"SUNSON_ImportSignValue,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);

		delete []CommandData;
		CommandData = NULL;
		g_mutex.Unlock(); 
		return 0;
	}
}

//导入RSA签名的DES密钥
int SUNSON_ImportRSADesKey(unsigned char nDESKeyId, unsigned char nRSAKeyId, unsigned char SignKeyId, long EncipherAlg, long SignAlg, long Dwuse,
											   int LpxValLen, unsigned char *LpxVal, int LpxSignLen, unsigned char *LpxSign, unsigned char *ucResult)
{
	if(g_IsCom)
	{
		return SUNSON_SerialImportRSADesKey(nDESKeyId, nRSAKeyId, SignKeyId, EncipherAlg, SignAlg, Dwuse,LpxValLen, LpxVal, LpxSignLen,LpxSign,ucResult);
	}
g_mutex.Lock();
	g_Log.WriteLog("---RSA导入签名DES密钥值---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_ImportRSADesKey, nDESKeyId = %d,nRSAKeyId = %X, SignKeyId = %d, EncipherAlg = %ld, SignAlg = %lX, Dwuse = %ld",
		nDESKeyId, nRSAKeyId, SignKeyId, EncipherAlg, SignAlg, Dwuse);
	g_Log.WriteLog(csLog);
	*ucResult = 0x00;

	unsigned char *CommandData=new unsigned char[LpxValLen+LpxSignLen+255];
	memset(CommandData,0,LpxValLen+LpxSignLen+255);
	CommandData[0] = 0x1B;
	CommandData[1] = 0x52;
	CommandData[2] = 0x44;
	CommandData[3] = ((LpxValLen+LpxSignLen+20)/256) & 0xFF;
	CommandData[4] = ((LpxValLen+LpxSignLen+20)%256) & 0xFF;
	CommandData[5] = nDESKeyId;
	CommandData[6] = nRSAKeyId;
	CommandData[7] = SignKeyId;
	CommandData[8] = (EncipherAlg >> 24) & 0xFF;
	CommandData[9] = (EncipherAlg >> 16) & 0xFF;
	CommandData[10] = (EncipherAlg >> 8) & 0xFF;
	CommandData[11] = EncipherAlg & 0xFF;
	CommandData[12] = (SignAlg >> 24) & 0xFF;
	CommandData[13] = (SignAlg >> 16) & 0xFF;
	CommandData[14] = (SignAlg >> 8) & 0xFF;
	CommandData[15] = SignAlg & 0xFF;
	CommandData[16] = (Dwuse >> 24) & 0xFF;
	CommandData[17] = (Dwuse >> 16) & 0xFF;
	CommandData[18] = (Dwuse >> 8) & 0xFF;
	CommandData[19] = Dwuse & 0xFF;
	CommandData[20] = (LpxValLen/256) & 0xFF;
	CommandData[21] = (LpxValLen%256) & 0xFF;
	memcpy(&CommandData[22], LpxVal, LpxValLen);
	CommandData[LpxValLen+22] = (LpxSignLen/256) & 0xFF;
	CommandData[LpxValLen+23] = (LpxSignLen%256) & 0xFF;
	memcpy(&CommandData[LpxValLen+24], LpxSign, LpxSignLen);

	for (int i = 0; i < (LpxValLen+LpxSignLen+24); i++)
	{
		CommandData[LpxValLen+LpxSignLen+24] ^= CommandData[i];
	}
	CommandData[LpxValLen+LpxSignLen+25] = 0x0D;
	CommandData[LpxValLen+LpxSignLen+26] = 0x0A;
	int iRet=sendUsbData(CommandData,LpxValLen+LpxSignLen+27,2000);
	if(iRet==0)
	{
		int nRetlen = 0;
		int ReturnLen = recvData(ucResult, &nRetlen, 2000);
		ReturnLen = nRetlen;
		if (ReturnLen>0)
		{
			unsigned char temp[1024] = {0};
			hex_asc(ucResult,temp,ReturnLen);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_ImportRSADesKey, ucData = %s",temp);
			else
				sprintf(csLog,"SUNSON_ImportRSADesKey, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			sprintf(csLog,"SUNSON_ImportRSADesKey, ReturnInfo = 0x%02x(失败)",ucResult[0]);
			g_Log.WriteLog(csLog);
		}
		delete []CommandData;
		CommandData = NULL;

		g_mutex.Unlock(); 
		return ReturnLen;
	}
	else
	{
		sprintf(csLog,"SUNSON_ImportRSADesKey,failure! errorinfo = 0x%02x",ucResult[0]);
		g_Log.WriteLog(csLog);
		delete []CommandData;
		CommandData = NULL;

		g_mutex.Unlock(); 
		return 0;
	}
}

//导入RSAdes密钥分量 
int SUNSON_ImportRSADesKeyEx(unsigned char KeyLenMode, unsigned char KcvLenMode, unsigned char KeyCountMode, unsigned char nDESKeyId, unsigned char nRSAKeyId, unsigned char SignKeyId, long EncipherAlg, 					long SignAlg, long dwUse,
				int LpxValLen, unsigned char *LpxVal, int LpxSignLen, unsigned char *LpxSign, unsigned char *ucResult)
{
	if(g_IsCom)
	{
		return SUNSON_SerialImportRSADesKeyEx(KeyLenMode,KcvLenMode,KeyCountMode,nDESKeyId,nRSAKeyId,SignKeyId,EncipherAlg,SignAlg,dwUse,LpxValLen, LpxVal, LpxSignLen,LpxSign,ucResult);
	}
	g_Log.WriteLog("---RSA导入签名DES密钥分量---");
g_mutex.Lock();
	
	unsigned char tempKey[1024] = {0};
	hex_asc(LpxVal,tempKey,LpxValLen);
	char csLog[2048] = {0};
	sprintf(csLog,"SUNSON_ImportRSADesKeyEx, KeyLenMode=%d,KcvLenMode=%d,KeyCountMode=%d,nDESKeyId = %d,nRSAKeyId = %d, SignKeyId = %d, EncipherAlg = %ld, SignAlg = %ld, Dwuse = 0x%02lX, vallen=%d, signlen=%d, keyvalue=%s",
		KeyLenMode,KcvLenMode,KeyCountMode,nDESKeyId, nRSAKeyId, SignKeyId, EncipherAlg, SignAlg, dwUse, LpxValLen,LpxSignLen,(char*)tempKey);
	g_Log.WriteLog(csLog);
	*ucResult = 0x00;

	unsigned char CommandData[4096]={0};
	CommandData[0] = 0x1B;
	CommandData[1] = 0x41;
	CommandData[2] = 0x32;
	CommandData[3] = ((LpxValLen+LpxSignLen+21)/256) & 0xFF;
	CommandData[4] = ((LpxValLen+LpxSignLen+21)%256) & 0xFF;
	CommandData[5] = (KeyLenMode<<6) | (KcvLenMode<<4) | KeyCountMode;
	CommandData[6] = nDESKeyId;
	CommandData[7] = nRSAKeyId;
	CommandData[8] = SignKeyId;
	CommandData[9] = (EncipherAlg >> 24) & 0xFF;
	CommandData[10] = (EncipherAlg >> 16) & 0xFF;
	CommandData[11] = (EncipherAlg >> 8) & 0xFF;
	CommandData[12] = EncipherAlg & 0xFF;
	CommandData[13] = (SignAlg >> 24) & 0xFF;
	CommandData[14] = (SignAlg >> 16) & 0xFF;
	CommandData[15] = (SignAlg >> 8) & 0xFF;
	CommandData[16] = SignAlg & 0xFF;
	CommandData[17] = (dwUse >> 24) & 0xFF;
	CommandData[18] = (dwUse >> 16) & 0xFF;
	CommandData[19] = (dwUse >> 8) & 0xFF;
	CommandData[20] = dwUse & 0xFF;
	CommandData[21] = (LpxValLen/256) & 0xFF;
	CommandData[22] = (LpxValLen%256) & 0xFF;
	memcpy(&CommandData[23], LpxVal, LpxValLen);
	CommandData[LpxValLen+23] = (LpxSignLen/256) & 0xFF;
	CommandData[LpxValLen+24] = (LpxSignLen%256) & 0xFF;
	memcpy(&CommandData[LpxValLen+25], LpxSign, LpxSignLen);

	for (int i = 0; i < (LpxValLen+LpxSignLen+25); i++)
	{
		CommandData[LpxValLen+LpxSignLen+25] ^= CommandData[i];
	}
	CommandData[LpxValLen+LpxSignLen+26] = 0x0D;
	CommandData[LpxValLen+LpxSignLen+27] = 0x0A;

	int iRet=sendUsbData(CommandData,LpxValLen+LpxSignLen+28,2000);
	if(iRet==0)
	{
		int nRetlen = 0;
		int ReturnLen = recvData(ucResult, &nRetlen, 2000);
		ReturnLen = nRetlen;
		if (ReturnLen>0)
		{
			unsigned char temp[1024] = {0};
			hex_asc(ucResult,temp,ReturnLen);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_ImportRSADesKeyEx, ucData = %s",temp);
			else
				sprintf(csLog,"SUNSON_ImportRSADesKeyEx, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			sprintf(csLog,"SUNSON_ImportRSADesKeyEx, ReturnInfo = 0x%02x(失败)",ucResult[0]);
			g_Log.WriteLog(csLog);
		}

		g_mutex.Unlock(); 
		return ReturnLen;
	}
	else
	{
		sprintf(csLog,"SUNSON_ImportRSADesKeyEx,failure! errorinfo = 0x%02x",ucResult[0]);
		g_Log.WriteLog(csLog);

		g_mutex.Unlock(); 
		return 0;
	}
}

//导入EPPID和签名值 signAlg 签名算法
int SUNSON_ImportEppidAndSignData(unsigned char SignAlg, int nEppidLen, unsigned char *EPPID, int SignLen, unsigned char *SignData, unsigned char* ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialImportEppidAndSignData(SignAlg,nEppidLen,EPPID,SignLen,SignData,ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---导入EPPID和签名值---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_ImportEppidAndSignData,SignAlg = %02x,nEppidLen = %d, SignLen=%d",SignAlg,nEppidLen,SignLen);
	g_Log.WriteLog(csLog);

	int i=0, nReturnValue = 0;
	unsigned char CommandData[4096] = {0};
	CommandData[0] = 0x1B;
	CommandData[1] = 0x4C;
	CommandData[2] = 0x45;
	CommandData[3] = (nEppidLen + SignLen + 6)/256;
	CommandData[4] = (nEppidLen + SignLen + 6)%256;
	CommandData[5] = SignAlg;
	CommandData[6] = (nEppidLen >> 8) & 0xFF;
	CommandData[7] = nEppidLen & 0xFF;
	memcpy(&CommandData[8], EPPID, nEppidLen);
	CommandData[nEppidLen+8] = (SignLen >>8) & 0xFF;
	CommandData[nEppidLen+9] = SignLen & 0xFF;
	memcpy(&CommandData[nEppidLen+10], SignData, SignLen);
	for (i = 0; i < nEppidLen+SignLen+10; i++)
	{
		CommandData[nEppidLen+SignLen+10] ^=  CommandData[i];
	}
	CommandData[nEppidLen+SignLen+11] = 0x0D;
	CommandData[nEppidLen+SignLen+12] = 0x0A;

	i=sendUsbData(CommandData,13+nEppidLen+SignLen,2000);
	if(i==0)
	{
		int nLen = 0;
		nReturnValue=recv_ST(ReturnInfo, &nLen, 1000);
		if (nReturnValue ==0)
		{
			g_Log.WriteLog("SUNSON_ImportEppidAndSignData,success!");
		}
		else
		{
			sprintf(csLog,"SUNSON_ImportEppidAndSignData,failure! errorinfo1 = 0x%02x",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		g_mutex.Unlock(); 
		return nLen;	
	}
	else
	{
		sprintf(csLog,"SUNSON_ImportEppidAndSignData,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}

//导出EPPID和签名值
int SUNSON_ExportEppidAndSignData(unsigned char *SignAlg, int *nEppidLen, unsigned char *EPPID, int *SignLen, unsigned char *SignData, unsigned char* ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialExportEppidAndSignData(SignAlg,nEppidLen,EPPID,SignLen,SignData,ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---导出EPPID和签名值---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_ExportEppidAndSignData");
	g_Log.WriteLog(csLog);
	unsigned char ucData[2048]={0};
	int i = 0;

	unsigned char ucCommand[14] = {0x1B,0x45,0x45,0x00,0x01,0x00,0x0D,0x0A};
	for (i = 0; i < 5; i++)
	{
		ucCommand[5] ^= ucCommand[i];
	}
	i=sendUsbData(ucCommand,8,1000);
	if(i==0)
	{
		int nRetlen = 0;
		int ReturnLen = recvData(ucData, &nRetlen, 2000);
		ReturnLen = nRetlen;
		if (ReturnLen>0)
		{
			unsigned char temp[2046] = {0};
			hex_asc(ucData,temp,ReturnLen);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_ExportEppidAndSignData, ucData = %s",temp);
			else
				sprintf(csLog,"SUNSON_ExportEppidAndSignData, success");
			//解析数据
			*SignAlg = ucData[0];
			*nEppidLen = (ucData[1]<<8)|ucData[2];
			memcpy(EPPID, ucData+3, *nEppidLen);
			int nlen = 3+(*nEppidLen);
			*SignLen = (ucData[nlen]<<8)|ucData[nlen+1];
			memcpy(SignData, ucData+nlen+2, *SignLen);

			g_Log.WriteLog(csLog);
		}
		else
		{
			ReturnInfo[0] = ucData[0];
			sprintf(csLog,"SUNSON_ExportEppidAndSignData, ReturnInfo = 0x%02x(失败)",ucData[0]);
			g_Log.WriteLog(csLog);
		}
		g_mutex.Unlock(); 
		return ReturnLen;
	}
	else
	{
		ReturnInfo[0] = ucData[0];
		sprintf(csLog,"SUNSON_ExportEppidAndSignData,failure! errorinfo = 0x%02x",ucData[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}

//RSA公私钥运算 mode 0x00私钥运算 0x01公钥运算
int SUNSON_RSACompute(int ucKeyId, unsigned char ucMode, unsigned char Padding,unsigned char HashId,int DataLen,unsigned char *ucData,unsigned char *DataResult)
{
	if(g_IsCom)
	{
		return SUNSON_SerialRSACompute(ucKeyId,ucMode,Padding,HashId,DataLen,ucData,DataResult);
	}
g_mutex.Lock();
	g_Log.WriteLog("---RSA数据运算---");
	char csLog[1024] = {0};
	unsigned char temp[1024] = {0};
	hex_asc(ucData, temp, DataLen);
	sprintf(csLog,"SUNSON_RSACompute, KeyID = %d,ucMode = %d,Padding = %X, HashId = %X, datalen=%d",ucKeyId,ucMode, Padding, HashId,DataLen);
	g_Log.WriteLog(csLog);
	*DataResult = 0x00;
	if(g_bLogClearSecret == false)
	{
		sprintf(csLog,"data=%s",temp);
		g_Log.WriteLog(csLog);
	}

	unsigned char *CommandData=new unsigned char[DataLen+255];
	memset(CommandData,0,DataLen+255);
	CommandData[0] = 0x1B;
	CommandData[1] = 0x44;
	CommandData[2] = 0x53;
	CommandData[3] = ((DataLen + 7)/256) & 0xFF;
	CommandData[4] = ((DataLen + 7)%256) & 0xFF;
	CommandData[5] = ucKeyId;
	CommandData[6] = ucMode;
	CommandData[7] = Padding;
	CommandData[8] = HashId;
	CommandData[9] = (DataLen/256) & 0xFF;
	CommandData[10] = (DataLen%256) & 0xFF;
	memcpy(&CommandData[11], ucData, DataLen);
	for (int i = 0; i < DataLen+11; i++)
	{
		CommandData[DataLen+11] ^= CommandData[i];
	}
	CommandData[DataLen+12] = 0x0D;
	CommandData[DataLen+13] = 0x0A;
	int iRet=sendUsbData(CommandData,DataLen+14,2000);
	if(iRet==0)
	{
		int nRetlen = 0;
		int nReturnValue=recvData(DataResult, &nRetlen, 2000);
		nReturnValue = nRetlen;
		if (nReturnValue>0)
		{
			unsigned char temp[1024] = {0};
			hex_asc(DataResult,temp,nReturnValue);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_RSACompute, DataResult = %s",temp);
			else
				sprintf(csLog,"SUNSON_RSACompute, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			sprintf(csLog,"SUNSON_RSACompute, ReturnInfo = 0x%02x(失败)",DataResult[0]);
			g_Log.WriteLog(csLog);
		}
		delete [] CommandData;
		CommandData=NULL;
		g_mutex.Unlock(); 
		return nReturnValue;		
	}
	else
	{
		sprintf(csLog,"SUNSON_RSACompute failed, errorinfo = 0x%02x",DataResult[0]);
		g_Log.WriteLog(csLog);
		delete [] CommandData;
		CommandData=NULL;
		g_mutex.Unlock(); 
		return 0;
	}
}

//导出EPP键盘签名的EPPID
int SUNSON_ExportEPPsignEPPid(int SignKeyID, unsigned char SignAlgorithm, int *nEppidLen, unsigned char *EPPID, int *SignLen, unsigned char *SignData, unsigned char* ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialExportEPPsignEPPid(SignKeyID, SignAlgorithm, nEppidLen, EPPID, SignLen, SignData, ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---导出键盘自签名EPPID数据---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_ExportEPPsignEPPid,SignKeyID=%d,SignAlgorithm=%d",SignKeyID,SignAlgorithm);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	int ItemType = 0x01; //导出EPPID
	if(SignKeyID== 0xFFFF)
		SignKeyID = 0;

	int i=0;
	int nReturnValue=-1;
	unsigned char CommandData[255]={0};
	CommandData[0] = 0x1b;
	CommandData[1] = 0x49;
	CommandData[2] = 0x45;
	CommandData[3] = 0x00;
	CommandData[4] = 0x09;
	CommandData[5]=ItemType/256;
	CommandData[6]=ItemType%256;
	CommandData[7]=0x00;
	CommandData[8]=0x00;
	CommandData[9]=SignKeyID/256;
	CommandData[10]=SignKeyID%256;
	CommandData[11]=SignAlgorithm/256;
	CommandData[12]=SignAlgorithm%256;

	for(i=0;i<13;i++)
	{
		CommandData[13] ^= CommandData[i];
	}
	CommandData[14] = 0x0d;
	CommandData[15] = 0x0a;

	i=sendUsbData(CommandData,16,1000);
	if(i==0)
	{
		int nRetlen = 0;
		nReturnValue=recvData(ReturnInfo, &nRetlen, 5000);
		nReturnValue = nRetlen;
		if (nReturnValue > 0)
		{
			//解析数据
			*nEppidLen = (ReturnInfo[0]<<8)|ReturnInfo[1];
			memcpy(EPPID, ReturnInfo+2, *nEppidLen);
			int nlen = 2+(*nEppidLen);
			*SignLen = (ReturnInfo[nlen]<<8)|ReturnInfo[nlen+1];
			memcpy(SignData, ReturnInfo+nlen+2, *SignLen);

			g_Log.WriteLog("SUNSON_ExportEPPsignEPPid,success!");
		}
		else
		{
			sprintf(csLog,"SUNSON_ExportEPPsignEPPid,failure! errorinfo1 = 0x%02x",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		g_mutex.Unlock(); 
		return nReturnValue;
	}
	else 
	{
		sprintf(csLog,"SUNSON_ExportEPPsignEPPid,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}

//导出EPP键盘签名的公钥数据
int SUNSON_ExportEPPsignPublicKey(int keyID, int SignKeyID, unsigned char SignAlgorithm, int *PublicKeyLen, unsigned char* PublicKey,int *EppPrivatekeySignLen, unsigned char *EppPrivatekeySignData, int *SignLen, unsigned char *SignData, unsigned char* ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialExportEPPsignPublicKey(keyID, SignKeyID, SignAlgorithm, PublicKeyLen, PublicKey, EppPrivatekeySignLen, EppPrivatekeySignData,SignLen,SignData, ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---导出键盘自签名公钥数据---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_ExportEPPsignPublicKey,keyID=%d,SignKeyID=%d,SignAlgorithm=%d",keyID,SignKeyID,SignAlgorithm);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	int ItemType = 0x02; //导出公钥

	int i=0;
	int nReturnValue=-1;
	unsigned char CommandData[255]={0};
	CommandData[0] = 0x1b;
	CommandData[1] = 0x49;
	CommandData[2] = 0x45;
	CommandData[3] = 0x00;
	CommandData[4] = 0x09;
	CommandData[5]=ItemType/256;
	CommandData[6]=ItemType%256;
	CommandData[7]=keyID/256;
	CommandData[8]=keyID%256;
	CommandData[9]=SignKeyID/256;
	CommandData[10]=SignKeyID%256;
	CommandData[11]=SignAlgorithm/256;
	CommandData[12]=SignAlgorithm%256;

	for(i=0;i<13;i++)
	{
		CommandData[13] ^= CommandData[i];
	}
	CommandData[14] = 0x0d;
	CommandData[15] = 0x0a;

	i=sendUsbData(CommandData,16,1000);
	if(i==0)
	{
		int nRetlen = 0;
		nReturnValue=recvData(ReturnInfo, &nRetlen, 5000);
		nReturnValue = nRetlen;
		if (nReturnValue > 0)
		{
			//解析数据
			*PublicKeyLen = (ReturnInfo[0]<<8)|ReturnInfo[1];
			memcpy(PublicKey, ReturnInfo+2, *PublicKeyLen);

			int nlen = 2+(*PublicKeyLen);
			*EppPrivatekeySignLen = (ReturnInfo[nlen]<<8)|ReturnInfo[nlen+1];
			memcpy(EppPrivatekeySignData, ReturnInfo+nlen+2, *EppPrivatekeySignLen);

			int nlen2 = 2+ nlen + (*EppPrivatekeySignLen);
			*SignLen = (ReturnInfo[nlen2]<<8)|ReturnInfo[nlen2+1];
			memcpy(SignData, ReturnInfo+nlen2+2, *SignLen);
			g_Log.WriteLog("SUNSON_ExportEPPsignPublicKey,success!");
		}
		else
		{
			sprintf(csLog,"SUNSON_ExportEPPsignPublicKey,failure! errorinfo1 = 0x%02x",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		g_mutex.Unlock(); 
		return nReturnValue;
	}
	else 
	{
		sprintf(csLog,"SUNSON_ExportEPPsignPublicKey,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}

//设置RKL hash算法 0:NID_MD5, 1:NID_sha1, 2:NID_sha224, 3:NID_sha256
int SUNSON_SetHashMode(int nMode, unsigned char* ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialSetHashMode(nMode, ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---设置HASH MODE---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SetHashMode,nMode= %d",nMode);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	int i=0;
	int nReturnValue=-1;
	unsigned char CommandData[10]={0x1b,0x48,0x4D,0x00,0x02,0x00,0x00,0x0d,0x0a};
	CommandData[5]=nMode;
	CommandData[6]=CommandData[0]^CommandData[1]^CommandData[2]^CommandData[3]^CommandData[4]^CommandData[5];
	i=sendUsbData(CommandData,9,1000);
	if(i==0)
	{
		int nLen = 0;
		nReturnValue=recv_ST(ReturnInfo, &nLen, 1000);
		if (nReturnValue ==0)
		{
			g_Log.WriteLog("SUNSON_SetHashMode,success!");
		}
		else
		{
			sprintf(csLog,"SUNSON_SetHashMode,failure! errorinfo1 = 0x%02x",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		g_mutex.Unlock(); 
		return nLen;
	}
	else 
	{
		sprintf(csLog,"SUNSON_SetHashMode,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}

//获取SM2公钥的SM3 KCV值
int SUNSON_GetSM2keySM3kcv(int nSM2keyid, unsigned char* KCV)
{
	if(g_IsCom)
	{
		return SUNSON_SerialGetSM2keySM3kcv(nSM2keyid, KCV);
	}
g_mutex.Lock();
	g_Log.WriteLog("---获取SM2公钥的SM3KCV---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_GetSM2keySM3kcv,KeyId = %d",nSM2keyid);
	g_Log.WriteLog(csLog);
	*KCV = 0x00;

	int i=0;
	int nReturnValue=-1;
	unsigned char CommandData[20]={0x1b,0x4B,0x56,0x00,0x03,0x00,nSM2keyid,0x00,0x0d,0x0a};
	for(i=0;i<7;i++)
		CommandData[7]^=CommandData[i];

	i=sendUsbData(CommandData,10,1000);
	if(i==0)
	{
		int nRetlen = 0;
		nReturnValue=recvData(KCV, &nRetlen, 2000);
		nReturnValue = nRetlen;
		if (nReturnValue>0)
		{
			unsigned char temp[1024] = {0};
			hex_asc(KCV,temp,nReturnValue);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_GetSM2keySM3kcv success, kcv=%s", temp);
			else
				sprintf(csLog,"SUNSON_GetSM2keySM3kcv success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			sprintf(csLog,"SUNSON_GetSM2keySM3kcv, ReturnInfo =  0x%02x(失败)",KCV[0]);
			g_Log.WriteLog(csLog);
		}
		g_mutex.Unlock(); 
		return nReturnValue;
	}
	else 
	{
		sprintf(csLog,"SUNSON_GetSM2keySM3kcv, ReturnInfo = 0x%02x(失败)",KCV[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}
//导入SM2公钥
int SUNSON_ImportSM2publickey(int nSm2keyid, int nSignKeyid, int nKeyDatalen, unsigned char * KeyData, int nSM2keyattr, int nSignAlg, int nSignDatalen, unsigned char* SignData, unsigned char* ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialImportSM2publickey(nSm2keyid, nSignKeyid,nKeyDatalen, KeyData,nSM2keyattr,nSignAlg,nSignDatalen, SignData,ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---导入SM2公钥---");
	char csLog[5000] = {0};
	unsigned char tempkey[2048]={0};
	unsigned char tempsign[2048]={0};
	hex_asc(KeyData, tempkey, nKeyDatalen);
	hex_asc(SignData, tempsign, nSignDatalen);
	sprintf(csLog,"SUNSON_ImportSM2publickey, nSm2keyid = %d,SignkeyId = %X, nSM2keyattr = %d, SignAlg = %X, datalen =%d, signlen =%d",nSm2keyid, nSignKeyid, nSM2keyattr, nSignAlg, nKeyDatalen, nSignDatalen);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;
	if(g_bLogClearSecret == false)
	{
		sprintf(csLog,"Keydata=%s,SignData=%s",tempkey, tempsign);
		g_Log.WriteLog(csLog);
	}

	unsigned char *CommandData=new unsigned char[nKeyDatalen+nSignDatalen+255];
	memset(CommandData,0,nKeyDatalen+nSignDatalen+255);
	CommandData[0] = 0x1B;
	CommandData[1] = 0x53;
	CommandData[2] = 0x4D;
	CommandData[3] = ((nKeyDatalen + nSignDatalen + 11)/256) & 0xFF;
	CommandData[4] = ((nKeyDatalen + nSignDatalen + 11)%256) & 0xFF;
	CommandData[5] = nSm2keyid;
	CommandData[6] = nSignKeyid;
	memcpy(&CommandData[7], KeyData, nKeyDatalen);
	CommandData[nKeyDatalen+7] = (nSM2keyattr >> 24) & 0xFF;
	CommandData[nKeyDatalen+8] = (nSM2keyattr >> 16) & 0xFF;
	CommandData[nKeyDatalen+9] = (nSM2keyattr >> 8) & 0xFF;
	CommandData[nKeyDatalen+10] = nSM2keyattr & 0xFF;
	CommandData[nKeyDatalen+11] = (nSignAlg >> 24) & 0xFF;
	CommandData[nKeyDatalen+12] = (nSignAlg >> 16) & 0xFF;
	CommandData[nKeyDatalen+13] = (nSignAlg >> 8) & 0xFF;
	CommandData[nKeyDatalen+14] = nSignAlg & 0xFF;
	memcpy(&CommandData[nKeyDatalen+15], SignData, nSignDatalen);
	for (int i = 0; i < nKeyDatalen+nSignDatalen+15; i++)
	{
		CommandData[nKeyDatalen+nSignDatalen+15] ^= CommandData[i];
	}
	CommandData[nKeyDatalen+nSignDatalen+16] = 0x0D;
	CommandData[nKeyDatalen+nSignDatalen+17] = 0x0A;
	int iRet=sendUsbData(CommandData,nKeyDatalen+nSignDatalen+18,2000);
	if(iRet==0)
	{
		int nRetlen = 0;
		int ReturnLen = recvData(ReturnInfo, &nRetlen, 2000);
		if (ReturnLen==0)
		{
			//unsigned char temp[1024] = {0};
			//hex_asc(ReturnInfo,temp,nRetlen);
			sprintf(csLog,"SUNSON_ImportSM2publickey, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			sprintf(csLog,"SUNSON_ImportSM2publickey, ReturnInfo = 0x%02x(失败)",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		delete []CommandData;
		CommandData = NULL;

		g_mutex.Unlock(); 
		return nRetlen;
	}
	else
	{
		sprintf(csLog,"SUNSON_ImportSM2publickey,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		delete []CommandData;
		CommandData = NULL;
		g_mutex.Unlock(); 
		return 0;
	}
}
//导入带SM2签名的SM2加密的SM4密钥
int SUNSON_ImportSM4KeyUseSM2keySign(int nSM4keyid, int nSM2keyid, int nSignKeyid, int DecryptAlg, int SignAlg, long nKeyAttr, int nDatalen, unsigned char*Data, int nSignLen, unsigned char* SignData, unsigned char* ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialImportSM4KeyUseSM2keySign(nSM4keyid,nSM2keyid, nSignKeyid,DecryptAlg, SignAlg,nKeyAttr,nDatalen,Data, nSignLen,SignData,ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---导入带SM2签名的SM2加密的SM4密钥---");
	char csLog[5000] = {0};
	unsigned char tempkey[2048]={0};
	unsigned char tempsign[2048]={0};
	hex_asc(Data, tempkey, nDatalen);
	hex_asc(SignData, tempsign, nSignLen);
	sprintf(csLog,"SUNSON_ImportSM4KeyUseSM2keySign, nSM4keyid=%d,nSm2keyid = %d,SignkeyId = %X, DecryptAlg = %X, SignAlg = %X,nKeyAttr=%lX, datalen =%d, signlen =%d",nSM4keyid,nSM2keyid, nSignKeyid,DecryptAlg , SignAlg, nKeyAttr, nDatalen, nSignLen);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;
	if(g_bLogClearSecret == false)
	{
		sprintf(csLog,"Keydata=%s, SignData=%s",tempkey,tempsign);
		g_Log.WriteLog(csLog);
	}

	unsigned char *CommandData=new unsigned char[nDatalen+nSignLen+255];
	memset(CommandData,0,nDatalen+nSignLen+255);
	CommandData[0] = 0x1B;
	CommandData[1] = 0x53;
	CommandData[2] = 0x53;
	CommandData[3] = ((nDatalen + nSignLen + 20)/256) & 0xFF;
	CommandData[4] = ((nDatalen + nSignLen + 20)%256) & 0xFF;
	CommandData[5] = nSM4keyid;
	CommandData[6] = nSM2keyid;
	CommandData[7] = nSignKeyid;
	CommandData[8] = (DecryptAlg >> 24) & 0xFF;
	CommandData[9] = (DecryptAlg >> 16) & 0xFF;
	CommandData[10] = (DecryptAlg >> 8) & 0xFF;
	CommandData[11] = DecryptAlg & 0xFF;
	CommandData[12] = (SignAlg >> 24) & 0xFF;
	CommandData[13] = (SignAlg >> 16) & 0xFF;
	CommandData[14] = (SignAlg >> 8) & 0xFF;
	CommandData[15] = SignAlg & 0xFF;
	CommandData[16] = (nKeyAttr >> 24) & 0xFF;
	CommandData[17] = (nKeyAttr >> 16) & 0xFF;
	CommandData[18] = (nKeyAttr >> 8) & 0xFF;
	CommandData[19] = nKeyAttr & 0xFF;
	CommandData[20] = nDatalen/256;
	CommandData[21] = nDatalen%256;
	memcpy(&CommandData[22], Data, nDatalen);
	CommandData[nDatalen+22] = nSignLen/256;
	CommandData[nDatalen+23] = nSignLen%256;
	memcpy(&CommandData[nDatalen+24], SignData, nSignLen);
	for (int i = 0; i < nDatalen+nSignLen+24; i++)
	{
		CommandData[nDatalen+nSignLen+24] ^= CommandData[i];
	}
	CommandData[nDatalen+nSignLen+25] = 0x0D;
	CommandData[nDatalen+nSignLen+26] = 0x0A;
	int iRet=sendUsbData(CommandData,nDatalen+nSignLen+27,2000);
	if(iRet==0)
	{
		int nRetlen = 0;
		int ReturnLen = recvData(ReturnInfo, &nRetlen, 2000);
		if (ReturnLen==0)
		{
			unsigned char temp[1024] = {0};
			hex_asc(ReturnInfo,temp,nRetlen);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_ImportSM4KeyUseSM2keySign, ucData = %s",temp);
			else
				sprintf(csLog,"SUNSON_ImportSM4KeyUseSM2keySign, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			sprintf(csLog,"SUNSON_ImportSM4KeyUseSM2keySign, ReturnInfo = 0x%02x(失败)",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		delete []CommandData;
		CommandData = NULL;

		g_mutex.Unlock(); 
		return nRetlen;
	}
	else
	{
		sprintf(csLog,"SUNSON_ImportSM4KeyUseSM2keySign,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		delete []CommandData;
		CommandData = NULL;
		g_mutex.Unlock(); 
		return 0;
	}
}
//导出SM2公钥签名
int SUNSON_ExportSM2publickeySignData(int nSM2keyid, unsigned char* SignData)
{
	if(g_IsCom)
	{
		return SUNSON_SerialExportSM2publickeySignData(nSM2keyid,SignData);
	}
g_mutex.Lock();
	g_Log.WriteLog("---导出SM2公钥签名---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_ExportSM2publickeySignData,KeyId = %d",nSM2keyid);
	g_Log.WriteLog(csLog);
	*SignData = 0x00;

	int i=0;
	int nReturnValue=-1;
	unsigned char CommandData[20]={0x1b,0x45,0x47,0x00,0x03,0x00,nSM2keyid,0x00,0x0d,0x0a};
	for(i=0;i<7;i++)
		CommandData[7]^=CommandData[i];

	i=sendUsbData(CommandData,10,1000);
	if(i==0)
	{
		int nRetlen = 0;
		nReturnValue=recvData(SignData, &nRetlen, 2000);
		if (nReturnValue==0)
		{
			unsigned char temp[1024] = {0};
			hex_asc(SignData,temp,nRetlen);
			if(g_bLogClearSecret == false)
				sprintf(csLog,"SUNSON_ExportSM2publickeySignData success, SignData=%s", temp);
			else
				sprintf(csLog,"SUNSON_ExportSM2publickeySignData success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			sprintf(csLog,"SUNSON_ExportSM2publickeySignData, ReturnInfo =  0x%02x(失败)",SignData[0]);
			g_Log.WriteLog(csLog);
		}
		g_mutex.Unlock(); 
		return nRetlen;
	}
	else 
	{
		sprintf(csLog,"SUNSON_ExportSM2publickeySignData, ReturnInfo = 0x%02x(失败)",SignData[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}
//导入SM2公钥签名
int SUNSON_ImportSM2publickeySignData(int nSM2keyid, int nSignlen, unsigned char* SignData, unsigned char* ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialImportSM2publickeySignData(nSM2keyid,nSignlen, SignData, ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---导入SM2公钥签名---");
	char csLog[5000] = {0};
	unsigned char tempsign[2048]={0};
	hex_asc(SignData, tempsign, nSignlen);
	sprintf(csLog,"SUNSON_ImportSM2publickeySignData, nSm2keyid = %d,signlen =%d",nSM2keyid, nSignlen);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;
	if(g_bLogClearSecret == false)
	{
		sprintf(csLog,"SignData=%s", tempsign);
		g_Log.WriteLog(csLog);
	}

	unsigned char *CommandData=new unsigned char[nSignlen+255];
	memset(CommandData,0,nSignlen+255);
	CommandData[0] = 0x1B;
	CommandData[1] = 0x49;
	CommandData[2] = 0x47;
	CommandData[3] = ((nSignlen + 3)/256) & 0xFF;
	CommandData[4] = ((nSignlen + 3)%256) & 0xFF;
	CommandData[5] = 0x00;
	CommandData[6] = nSM2keyid;
	memcpy(&CommandData[7], SignData, nSignlen);
	for (int i = 0; i < nSignlen+7; i++)
	{
		CommandData[nSignlen+7] ^= CommandData[i];
	}
	CommandData[nSignlen+8] = 0x0D;
	CommandData[nSignlen+9] = 0x0A;
	int iRet=sendUsbData(CommandData,nSignlen+10,1000);
	if(iRet==0)
	{
		int nRetlen = 0;
		int ReturnLen = recv_ST(ReturnInfo, &nRetlen, 1000);
		if (ReturnLen==0)
		{
			sprintf(csLog,"SUNSON_ImportSM2publickeySignData, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			sprintf(csLog,"SUNSON_ImportSM2publickeySignData, ReturnInfo = 0x%02x(失败)",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		delete []CommandData;
		CommandData = NULL;

		g_mutex.Unlock(); 
		return nRetlen;
	}
	else
	{
		sprintf(csLog,"SUNSON_ImportSM4KeyUseSM2keySign,failure! errorinfo = 0x%02x",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		delete []CommandData;
		CommandData = NULL;
		g_mutex.Unlock(); 
		return 0;
	}
}
//设置签名者ID
int SUNSON_SetSignUserID(int nUserIDLen, unsigned char *UserID, unsigned char* ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialSetSignUserID(nUserIDLen, UserID, ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---设置签名者ID---");
	char csLog[1024] = {0};
	unsigned char uctemp[1024]={0};
	hex_asc(UserID, uctemp, nUserIDLen);
	sprintf(csLog,"SUNSON_SetSignUserID, nUserIDLen=%d,UserID = %s",nUserIDLen, uctemp);
	g_Log.WriteLog(csLog);
	*ReturnInfo = 0x00;

	int i=0;
	int nReturnValue=-1;
	unsigned char *CommandData=new unsigned char[nUserIDLen+255];
	memset(CommandData,0,nUserIDLen+255);
	CommandData[0] = 0x1b;
	CommandData[1] = 0x53;
	CommandData[2] = 0x43;
	CommandData[3] = (nUserIDLen+1)/256;
	CommandData[4] = (nUserIDLen+1)%256;
	for (i = 0; i < nUserIDLen; i++)
	{
		CommandData[5+i] = UserID[i];
	}

	for(i=0; i < (5+nUserIDLen); i++)
		CommandData[5+nUserIDLen]^=CommandData[i];

	CommandData[6 + nUserIDLen ]=0x0d;
	CommandData[7 + nUserIDLen]=0x0a;

	i = sendUsbData(CommandData,8 +nUserIDLen,1000);
	if(0  == i)
	{
		int nRetlen = 0;
		nReturnValue = recv_ST(ReturnInfo, &nRetlen, 1000);
		if (nReturnValue == 0)
		{
			sprintf(csLog,"SUNSON_SetSignUserID, success");
			g_Log.WriteLog(csLog);
		}
		else
		{
			sprintf(csLog,"SUNSON_SetSignUserID, ReturnInfo = 0x%02x(失败)",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
		}
		delete [] CommandData;
		CommandData=NULL;
		g_mutex.Unlock(); 
		return nRetlen;		
	}
	else
	{
		sprintf(csLog,"SUNSON_SetSignUserID failed, errorcode = 0x%02x(失败)",ReturnInfo[0]);
		g_Log.WriteLog(csLog);
		delete [] CommandData;
		CommandData=NULL;
		g_mutex.Unlock(); 
		return 0;
	}
}

//民生银行版本接口 设置设备信息
//nType  0x30:厂商信息  最大10个字符
//       0x31:EPP信息   最大20个字符
//       0x32:键盘序列号  最大30个字符
//       0x33:驱动库名称  最大30个字符
int SUNSON_SetDeviceInfo(int nType, unsigned char* InfoData)
{
	if(g_IsCom)
	{
		return SUNSON_SerialSetDeviceInfo(nType, InfoData);
	}
	CCriticalSection autoSc;
	g_Log.WriteLog("---设置设备信息---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_SetDeviceInfo, nType=%d, Info=%s", nType, InfoData);
	g_Log.WriteLog(csLog);
	unsigned char ucData[256]={0};
	int i = 0;

	int nMaxLen=0;
	int len = strlen((char*)InfoData);
	switch(nType)
	{
	case 0x30:
		nMaxLen = 10;
		break;
	case 0x31:
		nMaxLen = 20;
		break;
	case 0x32:
		nMaxLen = 30;
		break;
	case 0x33:
		nMaxLen = 30;
		break;
	default:
		g_Log.WriteLog("无效参数");
		return 0;
	}

	if(len > nMaxLen)
	{
		g_Log.WriteLog("数据参数非法");
		return 0;
	}

	unsigned char ucCommand[128] = {0x1B,0x57,0x53,0x00,0x00,nType,0x00,0x00,0x00};
	ucCommand[3] = (2+len)/256;
	ucCommand[4] = (2+len)%256;

	memcpy(ucCommand+6,InfoData, len);

	for (i = 0; i < (6+len); i++)
	{
		ucCommand[6+len] ^= ucCommand[i];
	}
	ucCommand[7+len] = 0x0d;
	ucCommand[8+len] = 0x0a;

	i = sendUsbData(ucCommand,9+len,1000);
	if(i==0)
	{
		int nRetlen = 0;
		int ReturnLen = recv_ST(ucData, &nRetlen, 1000);
		if (ReturnLen==0)
		{
			g_Log.WriteLog("SUNSON_SetDeviceInfo, 成功");
		}
		else
		{
			sprintf(csLog,"SUNSON_SetDeviceInfo, ReturnInfo = 0x%02X(失败)",ucData[0]);
			g_Log.WriteLog(csLog);
		}
		return ReturnLen;
	}
	else
	{
		sprintf(csLog,"SUNSON_SetDeviceInfo,failure! errorinfo = 0x%02x",ucData[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}
//民生银行版本指令 读取设备信息
int SUNSON_GetDeviceInfo(unsigned char* DevName, unsigned char* EppName, unsigned char* EppNo, unsigned char* DriName)
{
	if(g_IsCom)
	{
		return SUNSON_SerialGetDeviceInfo(DevName, EppName, EppNo, DriName);
	}
	CCriticalSection autoSc;
	g_Log.WriteLog("---读取设备信息---");
	char csLog[1024] = {0};
	unsigned char ucData[256]={0};
	int i = 0;

	unsigned char ucCommand[12] = {0x1B,0x57,0x47,0x0d};
	i = sendUsbData(ucCommand,4,1000);
	if(i==0)
	{
		int nRetlen = 0;
		int ReturnLen = recvDataCMBC(ucData, &nRetlen, 1000);
		if (ReturnLen==0)
		{
			memcpy(DevName, ucData, 10);
			memcpy(EppName, ucData+10, 20);
			memcpy(EppNo, ucData+30, 30);
			memcpy(DriName, ucData+60, 30);
			g_Log.WriteLog("SUNSON_GetDeviceInfo, 成功");
		}
		else
		{
			sprintf(csLog,"SUNSON_GetDeviceInfo, ReturnInfo = 0x%02X(失败)",ucData[0]);
			g_Log.WriteLog(csLog);
		}
		return ReturnLen;
	}
	else
	{
		sprintf(csLog,"SUNSON_GetDeviceInfo,failure! errorinfo = 0x%02x",ucData[0]);
		g_Log.WriteLog(csLog);
		return 0;
	}
}

//导出SM2的EPPID和签名值 
int SUNSON_ExportSM2EppidAndSignData(unsigned char *SignAlg, int *nEppidLen, unsigned char *EPPID, int *SignLen, unsigned char *SignData, unsigned char* ReturnInfo)
{
	if(g_IsCom)
	{
		return SUNSON_SerialExportSM2EppidAndSignData(SignAlg,nEppidLen,EPPID,SignLen,SignData,ReturnInfo);
	}
g_mutex.Lock();
	g_Log.WriteLog("---导出SM2的EPPID和签名值---");
	char csLog[1024] = {0};
	sprintf(csLog,"SUNSON_ExportSM2EppidAndSignData");
	g_Log.WriteLog(csLog);
	unsigned char ucData[2048]={0};
	int i = 0;
	
	unsigned char ucCommand[14] = {0x1B,0x45,0x45,0x00,0x02,0x00,0x00,0x0D,0x0A};
	for (i = 0; i < 6; i++)
	{
		ucCommand[6] ^= ucCommand[i];
	}

	//unsigned char ReturnTxt[1024] = {0};
	int nRetLen = -1;

	i=sendUsbData(ucCommand,9, 1000);
	if(i==0)
	{
		int ReturnLen = recvData(ucData, &nRetLen, 1000);
		if (ReturnLen==0)
		{
			unsigned char temp[2046] = {0};
			hex_asc(ucData,temp,nRetLen);
			sprintf(csLog,"SUNSON_ExportSM2EppidAndSignData, ucData = %s",temp);
			//解析数据
			*SignAlg = 1;
			*nEppidLen = (ucData[1]<<8)|ucData[2];
			memcpy(EPPID, ucData+3, *nEppidLen);
			int nlen = 3+(*nEppidLen);
			*SignLen = (ucData[nlen]<<8)|ucData[nlen+1];
			memcpy(SignData, ucData+nlen+2, *SignLen);

			g_Log.WriteLog(csLog);
		}
		else
		{
			ReturnInfo[0] = ucData[0];
			sprintf(csLog,"SUNSON_ExportSM2EppidAndSignData, ReturnInfo = 0x%02x(失败)",ReturnInfo[0]);
			g_Log.WriteLog(csLog);
			g_mutex.Unlock(); 
			return 0;
		}
		g_mutex.Unlock(); 
		return nRetLen;
	}
	else
	{
		ReturnInfo[0] = ucData[0];
		sprintf(csLog,"SUNSON_ExportSM2EppidAndSignData,failure! errorinfo = 0x%02x",ucData[0]);
		g_Log.WriteLog(csLog);
		g_mutex.Unlock(); 
		return 0;
	}
}

//获取键盘序列号
int SUNSON_ReadSN(unsigned char*SerialNumber)
{
	if(g_IsCom)
	{
		return SUNSON_SerialReadSN(SerialNumber);
	}
g_mutex.Lock();
	g_Log.WriteLog("---取EPP序列号---");
	g_Log.WriteLog("SUNSON_ReadSN");
	char csLog[1024] =
	{ 0 };
	*SerialNumber = 0x00;

	int i = 0;
	int nReturnValue = -1;
	unsigned char CommandData[8] =
	{ 0x1b, 0x52, 0x53, 0x00, 0x01, 0x00, 0x0d, 0x0a };
	CommandData[5] = CommandData[0] ^ CommandData[1] ^ CommandData[2]
			^ CommandData[3] ^ CommandData[4];
	i = sendUsbData(CommandData, 8, 1000);
	if (i == 0)
	{
		int nRetlen = 0;
		nReturnValue = recvData(SerialNumber, &nRetlen, 3000);
		if (nReturnValue == 0)
		{
			unsigned char temp[1024] =
			{ 0 };
			hex_asc(SerialNumber, temp, nRetlen);
			sprintf(csLog, "SUNSON_ReadSN, sn = %s", temp);
			g_Log.WriteLog(csLog);
		}
		else
		{
			sprintf(csLog, "SUNSON_ReadSN, ReturnInfo = 0x%02x(失败)",
					SerialNumber[0]);
			g_Log.WriteLog(csLog);
		}

		g_mutex.Unlock(); 
		return nRetlen;
	}
	else
	{
		sprintf(csLog, "SUNSON_ReadSN, send error ReturnInfo = 0x%02x(失败)",
				SerialNumber[0]);
		g_Log.WriteLog(csLog);

		g_mutex.Unlock(); 
		return 0;
	}
}

//新增与F35相同的接口，方便开发调用代码保持一致
//1.45 切换算法 0x00 DES/3DES ; 0x02 SM4
int SUNSON_SwitchArithmetic(unsigned char ArithmeticType,unsigned char *DataResult)
{
	if(ArithmeticType == 0x02)
	{
		ArithmeticType = 0x01;
	}
	
	return SUNSON_SetEPPSMMode(ArithmeticType);
}

//设置卡键时间
int SUNSON_SetStuckKeyTimeOut(unsigned char TimeOut,unsigned char *ReturnInfo)
{
	return SUNSON_SetLockKeyTimeOut(TimeOut, ReturnInfo);
}

//获取键盘固件版本
int SUNSON_GetFirmwareVer(unsigned char *ucFirmwareVer)
{
	return SUNSON_GetVersionNo(ucFirmwareVer);
}

//1.43 下载SM4密钥
int SUNSON_LoadSM4Key(int ucKeyId,int ucDecryptKeyId,int KeyAttribute,unsigned char ucKeyLen,unsigned char *KeyValue,unsigned char *ReturnInfo)
{
	return SUNSON_LoadUserKey(ucKeyId, ucDecryptKeyId, KeyAttribute, ucKeyLen, KeyValue, ReturnInfo);
}

//USB键盘使能 系统键盘功能 ,0 关闭，1打开
int SUNSON_EnableSystemKeyboard(unsigned char nFlag,unsigned char *ReturnInfo)
{
	return SUNSON_EnableUSBplaintext(nFlag+1);
}


//设置日志目录
int SUNSON_SetLogPath(char * sLogPath, int nLevel)
{
	g_nLogLevel = nLevel;
	// strcpy(m_strWorkPath, sLogPath);
	return 1;
}


}
